diff --git a/DICUI.Forms/App.config b/DICUI.Forms/App.config
new file mode 100644
index 00000000..731f6de6
--- /dev/null
+++ b/DICUI.Forms/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DICUI/UI/AllowedSpeeds.cs b/DICUI.Forms/Constants.cs
similarity index 71%
rename from DICUI/UI/AllowedSpeeds.cs
rename to DICUI.Forms/Constants.cs
index 747caae6..678aef96 100644
--- a/DICUI/UI/AllowedSpeeds.cs
+++ b/DICUI.Forms/Constants.cs
@@ -4,13 +4,18 @@ using System.Linq;
using System.Windows.Media;
using DICUI.Data;
-namespace DICUI.UI
+namespace DICUI
{
///
- /// Gets allowed drive speeds for a given media type
+ /// Variables for UI elements
///
- public static class AllowedSpeeds
+ public static class Constants
{
+ public const string StartDumping = "Start Dumping";
+ public const string StopDumping = "Stop Dumping";
+
+ public const int LogWindowMarginFromMainWindow = 10;
+
// Private lists of known drive speed ranges
private static IReadOnlyList cd { get; } = new List { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 };
private static IReadOnlyList dvd { get; } = cd.Where(s => s <= 24).ToList();
@@ -22,7 +27,7 @@ namespace DICUI.UI
///
/// MediaType? that represents the current item
/// Read-only list of drive speeds
- public static IReadOnlyList GetForMediaType(MediaType? type)
+ public static IReadOnlyList GetSpeedsForMediaType(MediaType? type)
{
switch (type)
{
@@ -42,9 +47,9 @@ namespace DICUI.UI
}
// Create collections for UI based on known drive speeds
- public static DoubleCollection ForCDAsCollection { get; } = GetDoubleCollectionFromIntList(cd);
- public static DoubleCollection ForDVDAsCollection { get; } = GetDoubleCollectionFromIntList(dvd);
- public static DoubleCollection ForBDAsCollection { get; } = GetDoubleCollectionFromIntList(bd);
+ public static DoubleCollection SpeedsForCDAsCollection { get; } = GetDoubleCollectionFromIntList(cd);
+ public static DoubleCollection SpeedsForDVDAsCollection { get; } = GetDoubleCollectionFromIntList(dvd);
+ public static DoubleCollection SpeedsForBDAsCollection { get; } = GetDoubleCollectionFromIntList(bd);
private static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList list)
=> new DoubleCollection(list.Select(i => Convert.ToDouble(i)).ToList());
}
diff --git a/DICUI.Forms/DICUI.Forms.csproj b/DICUI.Forms/DICUI.Forms.csproj
new file mode 100644
index 00000000..b3251bcd
--- /dev/null
+++ b/DICUI.Forms/DICUI.Forms.csproj
@@ -0,0 +1,116 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {A6719A99-BF0E-4637-9A8E-CB38B1E16971}
+ WinExe
+ DICUI.Forms
+ DICUI.Forms
+ v4.6.1
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ Icon.ico
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Settings1.settings
+
+
+
+ Form
+
+
+ LogWindow.cs
+
+
+ Form
+
+
+ MainWindow.cs
+
+
+
+
+ Form
+
+
+ OptionsWindow.cs
+
+
+ LogWindow.cs
+
+
+ MainWindow.cs
+ Designer
+
+
+ OptionsWindow.cs
+
+
+
+
+
+ SettingsSingleFileGenerator
+ Settings1.Designer.cs
+
+
+
+
+
+
+
+ {51ab0928-13f9-44bf-a407-b6957a43a056}
+ DICUI.Library
+
+
+
+
\ No newline at end of file
diff --git a/DICUI.Forms/EnumDescriptionConverter.cs b/DICUI.Forms/EnumDescriptionConverter.cs
new file mode 100644
index 00000000..1526b272
--- /dev/null
+++ b/DICUI.Forms/EnumDescriptionConverter.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using DICUI.Data;
+using DICUI.Utilities;
+
+namespace DICUI.Forms
+{
+ ///
+ /// Used to provide a converter to XAML files to render comboboxes with enum values
+ ///
+ public class EnumDescriptionConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is DICCommand)
+ return ((DICCommand)value).Name();
+ else if (value is DICFlag)
+ return ((DICFlag)value).Name();
+ else if (value is MediaType?)
+ return ((MediaType?)value).Name();
+ else if (value is KnownSystem?)
+ return ((KnownSystem?)value).Name();
+ else
+ return "";
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return string.Empty;
+ }
+ }
+}
diff --git a/DICUI.Forms/Icon.ico b/DICUI.Forms/Icon.ico
new file mode 100644
index 00000000..370e6559
Binary files /dev/null and b/DICUI.Forms/Icon.ico differ
diff --git a/DICUI.Forms/KnownSystemComboBoxItem.cs b/DICUI.Forms/KnownSystemComboBoxItem.cs
new file mode 100644
index 00000000..c9c70b56
--- /dev/null
+++ b/DICUI.Forms/KnownSystemComboBoxItem.cs
@@ -0,0 +1,35 @@
+using System.Windows.Media;
+using DICUI.Data;
+using DICUI.Utilities;
+
+namespace DICUI
+{
+ ///
+ /// Represents a single item in the System combo box
+ ///
+ 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; } // TODO: Re-enable this
+
+ 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.Forms/Options.cs b/DICUI.Forms/Options.cs
new file mode 100644
index 00000000..aef39fa1
--- /dev/null
+++ b/DICUI.Forms/Options.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Configuration;
+using System.Reflection;
+using DICUI.Data;
+
+namespace DICUI
+{
+ public class Options
+ {
+ public string DefaultOutputPath { get; private set; }
+ public string DICPath { get; private set; }
+ public string SubDumpPath { get; private set; }
+
+ public int preferredDumpSpeedCD { get; set; }
+ public int preferredDumpSpeedDVD { get; set; }
+ public int preferredDumpSpeedBD { get; set; }
+
+ public bool QuietMode { get; set; }
+ public bool ParanoidMode { get; set; }
+ public bool ScanForProtection { get; set; }
+ public int RereadAmountForC2 { get; set; }
+
+ public bool SkipMediaTypeDetection { get; set; }
+
+ public bool VerboseLogging { get; set; }
+ public bool OpenLogWindowAtStartup { get; set; }
+
+ public void Save()
+ {
+ Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
+
+ //TODO: reflection is used
+ //TODO: is remove needed, doesn't the value get directly overridden
+ Array.ForEach(
+ GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance),
+ p => {
+ configFile.AppSettings.Settings.Remove(p.Name);
+ configFile.AppSettings.Settings.Add(p.Name, Convert.ToString(p.GetValue(this)));
+ }
+ );
+
+ configFile.Save(ConfigurationSaveMode.Modified);
+ }
+
+ public void Load()
+ {
+ //TODO: hardcoded, we should find a better way
+ DICPath = ConfigurationManager.AppSettings["DICPath"] ?? @"Programs\DiscImageCreator.exe";
+ SubDumpPath = ConfigurationManager.AppSettings["SubDumpPath"] ?? "subdump.exe";
+ DefaultOutputPath = ConfigurationManager.AppSettings["DefaultOutputPath"] ?? "ISO";
+
+ this.preferredDumpSpeedCD = Int32.TryParse(ConfigurationManager.AppSettings["preferredDumpSpeedCD"], out int maxDumpSpeedCD) ? maxDumpSpeedCD : 72;
+ this.preferredDumpSpeedDVD = Int32.TryParse(ConfigurationManager.AppSettings["preferredDumpSpeedDVD"], out int maxDumpSpeedDVD) ? maxDumpSpeedDVD : 24;
+ this.preferredDumpSpeedBD = Int32.TryParse(ConfigurationManager.AppSettings["preferredDumpSpeedBD"], out int maxDumpSpeedBD) ? maxDumpSpeedBD : 16;
+
+ this.QuietMode = Boolean.TryParse(ConfigurationManager.AppSettings["QuietMode"], out bool quietMode) ? quietMode : false;
+ this.ParanoidMode = Boolean.TryParse(ConfigurationManager.AppSettings["ParanoidMode"], out bool paranoidMode) ? paranoidMode : false;
+ this.ScanForProtection = Boolean.TryParse(ConfigurationManager.AppSettings["ScanForProtection"], out bool scanForProtection) ? scanForProtection : true;
+ this.SkipMediaTypeDetection = Boolean.TryParse(ConfigurationManager.AppSettings["SkipMediaTypeDetection"], out bool skipMediaTypeDetection) ? skipMediaTypeDetection : false;
+ this.RereadAmountForC2 = Int32.TryParse(ConfigurationManager.AppSettings["RereadAmountForC2"], out int rereadAmountForC2) ? rereadAmountForC2 : 20;
+ this.VerboseLogging = Boolean.TryParse(ConfigurationManager.AppSettings["VerboseLogging"], out bool verboseLogging) ? verboseLogging : true;
+ this.OpenLogWindowAtStartup = Boolean.TryParse(ConfigurationManager.AppSettings["OpenLogWindowAtStartup"], out bool openLogWindowAtStartup) ? openLogWindowAtStartup : true;
+ }
+
+
+ //TODO: probably should be generic for non-string options
+ //TODO: using reflection for Set and Get is orthodox but it works, should be changed to a key,value map probably
+ public void Set(string key, string value)
+ {
+ GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).SetValue(this, value);
+ }
+
+ public string Get(string key)
+ {
+ return GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).GetValue(this) as string;
+ }
+
+ public int GetPreferredDumpSpeedForMediaType(MediaType? type)
+ {
+ switch (type)
+ {
+ case MediaType.CDROM:
+ case MediaType.GDROM:
+ return preferredDumpSpeedCD;
+ case MediaType.DVD:
+ case MediaType.HDDVD:
+ case MediaType.NintendoGameCube:
+ case MediaType.NintendoWiiOpticalDisc:
+ return preferredDumpSpeedDVD;
+ case MediaType.BluRay:
+ return preferredDumpSpeedBD;
+ default:
+ return 8;
+ }
+ }
+ }
+}
diff --git a/DICUI.Forms/Program.cs b/DICUI.Forms/Program.cs
new file mode 100644
index 00000000..c33e7636
--- /dev/null
+++ b/DICUI.Forms/Program.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Windows.Forms;
+using DICUI.Forms.Windows;
+
+namespace DICUI.Forms
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new MainWindow());
+ }
+ }
+}
diff --git a/DICUI.Forms/Properties/AssemblyInfo.cs b/DICUI.Forms/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..87137edc
--- /dev/null
+++ b/DICUI.Forms/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("DICUI.Forms")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DICUI.Forms")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a6719a99-bf0e-4637-9a8e-cb38b1e16971")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/DICUI.Forms/Properties/Settings1.Designer.cs b/DICUI.Forms/Properties/Settings1.Designer.cs
new file mode 100644
index 00000000..2a34933b
--- /dev/null
+++ b/DICUI.Forms/Properties/Settings1.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace DICUI.Forms.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")]
+ internal sealed partial class Settings1 : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings1 defaultInstance = ((Settings1)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings1())));
+
+ public static Settings1 Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/DICUI.Forms/Properties/Settings1.settings b/DICUI.Forms/Properties/Settings1.settings
new file mode 100644
index 00000000..049245f4
--- /dev/null
+++ b/DICUI.Forms/Properties/Settings1.settings
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/DICUI.Forms/ViewModels.cs b/DICUI.Forms/ViewModels.cs
new file mode 100644
index 00000000..445c7fb0
--- /dev/null
+++ b/DICUI.Forms/ViewModels.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Windows.Media;
+using DICUI.Forms.Windows;
+
+namespace DICUI.Forms
+{
+ public class OptionsViewModel
+ {
+ private Options _options;
+
+ public OptionsViewModel(Options options)
+ {
+ this._options = options;
+ }
+
+ public bool QuietMode
+ {
+ get { return _options.QuietMode; }
+ set { _options.QuietMode = value; }
+ }
+
+ public bool ParanoidMode
+ {
+ get { return _options.ParanoidMode; }
+ set { _options.ParanoidMode = value; }
+ }
+
+ public bool ScanForProtection
+ {
+ get { return _options.ScanForProtection; }
+ set { _options.ScanForProtection = value; }
+ }
+
+ public bool SkipMediaTypeDetection
+ {
+ get { return _options.SkipMediaTypeDetection; }
+ set { _options.SkipMediaTypeDetection = value; }
+ }
+
+ public string RereadAmountForC2
+ {
+ get { return Convert.ToString(_options.RereadAmountForC2); }
+ set
+ {
+ if (Int32.TryParse(value, out int result))
+ _options.RereadAmountForC2 = result;
+ }
+ }
+
+ public bool VerboseLogging
+ {
+ get { return _options.VerboseLogging; }
+ set
+ {
+ _options.VerboseLogging = value;
+ _options.Save();
+ }
+ }
+
+ public bool OpenLogWindowAtStartup
+ {
+ get { return _options.OpenLogWindowAtStartup; }
+ set
+ {
+ _options.OpenLogWindowAtStartup = value;
+ _options.Save();
+ }
+ }
+ }
+
+ public class LoggerViewModel
+ {
+ private LogWindow _logWindow;
+
+ public void SetWindow(LogWindow logWindow) => _logWindow = logWindow;
+
+ public bool WindowVisible
+ {
+ get => _logWindow != null ? _logWindow.Visible : false;
+ set
+ {
+ if (value)
+ {
+ _logWindow.AdjustPositionToMainWindow();
+ _logWindow.Show();
+ }
+ else
+ _logWindow.Hide();
+ }
+ }
+
+ public void VerboseLog(string text)
+ {
+ if (ViewModels.OptionsViewModel.VerboseLogging)
+ _logWindow.AppendToTextBox(text, System.Drawing.Color.Yellow);
+ }
+
+ public void VerboseLog(string format, params object[] args) => VerboseLog(string.Format(format, args));
+ public void VerboseLogLn(string format, params object[] args) => VerboseLog(string.Format(format, args) + "\n");
+ }
+
+ public static class ViewModels
+ {
+ public static OptionsViewModel OptionsViewModel { get; set; }
+ public static LoggerViewModel LoggerViewModel { get; set; } = new LoggerViewModel();
+ }
+}
diff --git a/DICUI.Forms/Windows/LogWindow.Designer.cs b/DICUI.Forms/Windows/LogWindow.Designer.cs
new file mode 100644
index 00000000..b6c67a69
--- /dev/null
+++ b/DICUI.Forms/Windows/LogWindow.Designer.cs
@@ -0,0 +1,175 @@
+namespace DICUI.Forms.Windows
+{
+ partial class LogWindow
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
+ this.progressBar = new System.Windows.Forms.ProgressBar();
+ this.output = new System.Windows.Forms.RichTextBox();
+ this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
+ this.Verbose = new System.Windows.Forms.CheckBox();
+ this.OpenAtStartupCheckBox = new System.Windows.Forms.CheckBox();
+ this.ClearButton = new System.Windows.Forms.Button();
+ this.HideButton = new System.Windows.Forms.Button();
+ this.tableLayoutPanel1.SuspendLayout();
+ this.tableLayoutPanel2.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // tableLayoutPanel1
+ //
+ this.tableLayoutPanel1.ColumnCount = 1;
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.tableLayoutPanel1.Controls.Add(this.progressBar, 0, 0);
+ this.tableLayoutPanel1.Controls.Add(this.output, 0, 1);
+ this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 2);
+ this.tableLayoutPanel1.Location = new System.Drawing.Point(12, 12);
+ this.tableLayoutPanel1.Name = "tableLayoutPanel1";
+ this.tableLayoutPanel1.RowCount = 3;
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
+ this.tableLayoutPanel1.Size = new System.Drawing.Size(560, 287);
+ this.tableLayoutPanel1.TabIndex = 0;
+ //
+ // progressBar
+ //
+ this.progressBar.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.progressBar.Location = new System.Drawing.Point(3, 3);
+ this.progressBar.Name = "progressBar";
+ this.progressBar.Size = new System.Drawing.Size(554, 34);
+ this.progressBar.TabIndex = 0;
+ //
+ // output
+ //
+ this.output.BackColor = System.Drawing.Color.DimGray;
+ this.output.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.output.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.output.Location = new System.Drawing.Point(3, 43);
+ this.output.Name = "output";
+ this.output.ReadOnly = true;
+ this.output.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical;
+ this.output.Size = new System.Drawing.Size(554, 201);
+ this.output.TabIndex = 1;
+ this.output.Text = "";
+ this.output.TextChanged += new System.EventHandler(this.OnTextChanged);
+ //
+ // tableLayoutPanel2
+ //
+ this.tableLayoutPanel2.ColumnCount = 5;
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15F));
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20F));
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 35F));
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15F));
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15F));
+ this.tableLayoutPanel2.Controls.Add(this.Verbose, 0, 0);
+ this.tableLayoutPanel2.Controls.Add(this.OpenAtStartupCheckBox, 1, 0);
+ this.tableLayoutPanel2.Controls.Add(this.ClearButton, 3, 0);
+ this.tableLayoutPanel2.Controls.Add(this.HideButton, 4, 0);
+ this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 250);
+ this.tableLayoutPanel2.Name = "tableLayoutPanel2";
+ this.tableLayoutPanel2.RowCount = 1;
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel2.Size = new System.Drawing.Size(554, 34);
+ this.tableLayoutPanel2.TabIndex = 2;
+ //
+ // Verbose
+ //
+ this.Verbose.AutoSize = true;
+ this.Verbose.Dock = System.Windows.Forms.DockStyle.Left;
+ this.Verbose.Location = new System.Drawing.Point(3, 3);
+ this.Verbose.Name = "Verbose";
+ this.Verbose.Size = new System.Drawing.Size(65, 28);
+ this.Verbose.TabIndex = 1;
+ this.Verbose.Text = "Verbose";
+ this.Verbose.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ this.Verbose.UseVisualStyleBackColor = true;
+ //
+ // OpenAtStartupCheckBox
+ //
+ this.OpenAtStartupCheckBox.AutoSize = true;
+ this.OpenAtStartupCheckBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.OpenAtStartupCheckBox.Location = new System.Drawing.Point(86, 3);
+ this.OpenAtStartupCheckBox.Name = "OpenAtStartupCheckBox";
+ this.OpenAtStartupCheckBox.Size = new System.Drawing.Size(104, 28);
+ this.OpenAtStartupCheckBox.TabIndex = 2;
+ this.OpenAtStartupCheckBox.Text = "Open at startup";
+ this.OpenAtStartupCheckBox.UseVisualStyleBackColor = true;
+ //
+ // ClearButton
+ //
+ this.ClearButton.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ClearButton.Location = new System.Drawing.Point(389, 3);
+ this.ClearButton.Name = "ClearButton";
+ this.ClearButton.Size = new System.Drawing.Size(77, 28);
+ this.ClearButton.TabIndex = 3;
+ this.ClearButton.Text = "Clear";
+ this.ClearButton.UseVisualStyleBackColor = true;
+ this.ClearButton.Click += new System.EventHandler(this.OnClearButton);
+ //
+ // HideButton
+ //
+ this.HideButton.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.HideButton.Location = new System.Drawing.Point(472, 3);
+ this.HideButton.Name = "HideButton";
+ this.HideButton.Size = new System.Drawing.Size(79, 28);
+ this.HideButton.TabIndex = 4;
+ this.HideButton.Text = "Hide";
+ this.HideButton.UseVisualStyleBackColor = true;
+ this.HideButton.SizeChanged += new System.EventHandler(this.ScrollViewer_SizeChanged);
+ this.HideButton.Click += new System.EventHandler(this.OnHideButton);
+ //
+ // LogWindow
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(584, 311);
+ this.Controls.Add(this.tableLayoutPanel1);
+ this.Name = "LogWindow";
+ this.ShowIcon = false;
+ this.Text = "Log Window";
+ this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnWindowClosed);
+ this.tableLayoutPanel1.ResumeLayout(false);
+ this.tableLayoutPanel2.ResumeLayout(false);
+ this.tableLayoutPanel2.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
+ private System.Windows.Forms.ProgressBar progressBar;
+ private System.Windows.Forms.RichTextBox output;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
+ private System.Windows.Forms.CheckBox Verbose;
+ private System.Windows.Forms.CheckBox OpenAtStartupCheckBox;
+ private System.Windows.Forms.Button ClearButton;
+ private System.Windows.Forms.Button HideButton;
+ }
+}
\ No newline at end of file
diff --git a/DICUI.Forms/Windows/LogWindow.cs b/DICUI.Forms/Windows/LogWindow.cs
new file mode 100644
index 00000000..d828f557
--- /dev/null
+++ b/DICUI.Forms/Windows/LogWindow.cs
@@ -0,0 +1,380 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Windows.Threading;
+
+namespace DICUI.Forms.Windows
+{
+ public partial class LogWindow : Form
+ {
+ private const int GWL_STYLE = -16;
+ private const int WS_SYSMENU = 0x80000;
+ [DllImport("user32.dll", SetLastError = true)]
+ private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
+ [DllImport("user32.dll")]
+ private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
+
+ private MainWindow _mainWindow;
+
+ private List _matchers;
+
+ volatile Process _process;
+
+ public LogWindow(MainWindow mainWindow)
+ {
+ InitializeComponent();
+
+ this._mainWindow = mainWindow;
+
+ _matchers = new List();
+
+ _matchers.Add(new Matcher(
+ "Descrambling data sector of img (LBA)",
+ @"\s*(\d+)\/\s*(\d+)$",
+ match => {
+ if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
+ {
+ float percentProgress = (current / (float)total) * 100;
+ progressBar.Value = (int)percentProgress;
+ //progressBar.Text = string.Format("Descrambling image.. ({0:##.##}%)", percentProgress);
+ }
+ }));
+
+ _matchers.Add(new Matcher(
+ @"Creating .scm (LBA)",
+ @"\s*(\d+)\/\s*(\d+)$",
+ match => {
+ if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
+ {
+ float percentProgress = (current / (float)total) * 100;
+ progressBar.Value = (int)percentProgress;
+ //progressBar.Text = string.Format("Creating scrambled image.. ({0:##.##}%)", percentProgress);
+ }
+ }));
+
+ _matchers.Add(new Matcher(
+ "Checking sectors (LBA)",
+ @"\s*(\d+)\/\s*(\d+)$",
+ match => {
+ if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
+ {
+ float percentProgress = (current / (float)total) * 100;
+ progressBar.Value = (int)percentProgress;
+ //progressBar.Text = string.Format("Checking for errors.. ({0:##.##}%)", percentProgress);
+ }
+ }));
+
+ _matchers.Add(new Matcher(
+ "Scanning sector (LBA)",
+ @"\s*(\d+)\/\s*(\d+)$",
+ match => {
+ if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
+ {
+ float percentProgress = (current / (float)total) * 100;
+ progressBar.Value = (int)percentProgress;
+ //progressBar.Text = string.Format("Scanning sectors for protection.. ({0:##.##}%)", percentProgress);
+ }
+ }));
+ }
+
+ protected override bool ShowWithoutActivation
+ {
+ get { return true; }
+ }
+
+ public void StartDump(string args)
+ {
+ AppendToTextBox(string.Format("Launching DIC with args: {0}\r\n", args), System.Drawing.Color.Orange);
+
+ Task.Run(() =>
+ {
+ _process = new Process()
+ {
+ StartInfo = new ProcessStartInfo()
+ {
+ FileName = @"Programs/DiscImageCreator.exe",
+ Arguments = args,
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ },
+ };
+
+ StreamState stdoutState = new StreamState(false);
+ StreamState stderrState = new StreamState(true);
+
+ //_cmd.ErrorDataReceived += (process, text) => Dispatcher.CurrentDispatcher.Invoke(() => UpdateConsole(text.Data, Brushes.Red));
+ _process.Start();
+
+ var _1 = ConsumeOutput(_process.StandardOutput, s => Dispatcher.CurrentDispatcher.Invoke(() => UpdateConsole(s, stdoutState)));
+ var _2 = ConsumeOutput(_process.StandardError, s => Dispatcher.CurrentDispatcher.Invoke(() => UpdateConsole(s, stderrState)));
+
+ _process.EnableRaisingEvents = true;
+ _process.Exited += OnProcessExit;
+ });
+ }
+
+ public void AdjustPositionToMainWindow()
+ {
+ this.Left = _mainWindow.Left;
+ this.Top = _mainWindow.Top + _mainWindow.Height + Constants.LogWindowMarginFromMainWindow;
+ this.BringToFront();
+ }
+
+ private void GracefullyTerminateProcess()
+ {
+ if (_process != null)
+ {
+ _process.Exited -= OnProcessExit;
+ bool isForced = !_process.HasExited;
+
+ if (isForced)
+ {
+ AppendToTextBox("\r\nForcefully Killing the process\r\n", System.Drawing.Color.Red);
+ _process.Kill();
+ _process.WaitForExit();
+ }
+
+ AppendToTextBox(string.Format("\r\nExit Code: {0}\r\n", _process.ExitCode), _process.ExitCode == 0 ? System.Drawing.Color.Green : System.Drawing.Color.Red);
+ if (_process.ExitCode == 0)
+ {
+ Dispatcher.CurrentDispatcher.Invoke(() =>
+ {
+ //progressBar.Text = "Done!";
+ progressBar.Value = 100;
+ progressBar.ForeColor = System.Drawing.Color.Green;
+ });
+ }
+ else
+ {
+ Dispatcher.CurrentDispatcher.Invoke(() =>
+ {
+ //progressBar.Text = isForced ? "Aborted by user" : "Error, please check log!";
+ progressBar.Value = 100;
+ progressBar.ForeColor = System.Drawing.Color.Red;
+ });
+ }
+
+ _process.Close();
+ }
+
+ _process = null;
+ }
+
+ private void ScrollViewer_SizeChanged(object sender, EventArgs e)
+ {
+ output.ScrollToCaret();
+ }
+
+ async Task ConsumeOutput(TextReader reader, Action callback)
+ {
+ char[] buffer = new char[256];
+ int cch;
+
+ while ((cch = await reader.ReadAsync(buffer, 0, buffer.Length)) > 0)
+ {
+ callback(new string(buffer, 0, cch));
+ }
+ }
+
+ // this is used to optimize the work since we need to process A LOT of text
+ struct Matcher
+ {
+ private readonly String prefix;
+ private readonly Regex regex;
+ private readonly int start;
+ private readonly Action lambda;
+
+ public Matcher(String prefix, String regex, Action lambda)
+ {
+ this.prefix = prefix;
+ this.regex = new Regex(regex);
+ this.start = prefix.Length;
+ this.lambda = lambda;
+ }
+
+ public bool Matches(ref string text) => text.StartsWith(prefix);
+
+ public void Apply(ref string text)
+ {
+ Match match = regex.Match(text, start);
+ lambda.Invoke(match);
+ }
+ }
+
+ private void ProcessStringForProgressBar(string text)
+ {
+ foreach (Matcher matcher in _matchers)
+ {
+ if (matcher.Matches(ref text))
+ {
+ matcher.Apply(ref text);
+ return;
+ }
+ }
+ }
+
+ class StreamState
+ {
+ public enum State
+ {
+ BEGIN,
+ READ_CARRIAGE,
+ };
+
+ public State state;
+ public readonly StringBuilder buffer;
+ public readonly bool isError;
+
+ public StreamState(bool isError)
+ {
+ this.state = State.BEGIN;
+ this.buffer = new StringBuilder();
+ this.isError = isError;
+ }
+
+ public bool HasData() => buffer.Length > 0;
+ public string Fetch() => buffer.ToString();
+ public void Clear() => buffer.Clear();
+ public void Append(char c) => buffer.Append(c);
+
+ public bool Is(State state) => this.state == state;
+ public void Set(State state) => this.state = state;
+ }
+
+ public void AppendToTextBox(string text, System.Drawing.Color color)
+ {
+ if (Dispatcher.CurrentDispatcher.CheckAccess())
+ {
+ output.ForeColor = color;
+ output.AppendText(text);
+ }
+ else
+ Dispatcher.CurrentDispatcher.Invoke(() =>
+ {
+ output.ForeColor = color;
+ output.AppendText(text);
+ });
+ }
+
+ private void UpdateConsole(string text, StreamState state)
+ {
+ /*if (c == '\r') { output.Inlines.Add(@"\r"); file.Write("\\r"); }
+ else if (c == '\n') { output.Inlines.Add(@"\n"); file.Write("\\n\n"); }
+ output.Inlines.Add(""+c);
+ file.Write(c);
+ file.Flush();
+ continue;*/
+
+ if (text != null)
+ {
+ foreach (char c in text)
+ {
+ switch (c)
+ {
+ case '\r' when (state.Is(StreamState.State.BEGIN)):
+ {
+ state.Set(StreamState.State.READ_CARRIAGE);
+ break;
+ }
+
+ case '\n' when (state.Is(StreamState.State.READ_CARRIAGE)):
+ {
+ if (state.buffer.Length > 0)
+ {
+ string buffer = state.Fetch();
+
+ AppendToTextBox(buffer, state.isError ? System.Drawing.Color.Red : System.Drawing.Color.White);
+
+ if (!state.isError)
+ ProcessStringForProgressBar(buffer);
+ }
+ output.AppendText(Environment.NewLine);
+ state.Clear();
+ state.Set(StreamState.State.BEGIN);
+ break;
+ }
+
+ default:
+ if (state.Is(StreamState.State.READ_CARRIAGE) && state.HasData())
+ {
+ if (!String.IsNullOrEmpty(output.Lines.Last()))
+ output.Lines[output.Lines.Length] = string.Empty;
+
+ string buffer = state.Fetch();
+
+ AppendToTextBox(buffer, state.isError ? System.Drawing.Color.Red : System.Drawing.Color.White);
+
+ if (!state.isError)
+ ProcessStringForProgressBar(buffer);
+
+ state.Clear();
+ }
+
+ state.Set(StreamState.State.BEGIN);
+ state.Append(c);
+ break;
+
+ }
+ }
+ }
+ }
+
+ #region EventHandlers
+
+ private void OnWindowClosed(object sender, FormClosedEventArgs e)
+ {
+ GracefullyTerminateProcess();
+ }
+
+ private void OnWindowLoaded(object sender, EventArgs e)
+ {
+ var hwnd = this.Handle;
+ SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
+ }
+
+ void OnProcessExit(object sender, EventArgs e)
+ {
+ //Dispatcher.CurrentDispatcher.Invoke(() => AbortButton.IsEnabled = false);
+ GracefullyTerminateProcess();
+ }
+
+ private void OnHideButton(object sender, EventArgs e)
+ {
+ ViewModels.LoggerViewModel.WindowVisible = false;
+ //TODO: this should be bound directly to WindowVisible property in two way fashion
+ // we need to study how to properly do it in XAML
+ _mainWindow.showLogWindowToolStripMenuItem.Checked = false;
+ }
+
+ private void OnClearButton(object sender, EventArgs e)
+ {
+ output.Clear();
+ }
+
+ private void OnAbortButton(object sender, EventArgs args)
+ {
+ GracefullyTerminateProcess();
+ }
+
+ private void OnStartButton(object sender, EventArgs args)
+ {
+ StartDump("cd e Gam.iso 16");
+ }
+
+ private void OnTextChanged(object sender, EventArgs e)
+ {
+ output.ScrollToCaret();
+ }
+
+ #endregion
+ }
+}
diff --git a/DICUI.Forms/Windows/LogWindow.resx b/DICUI.Forms/Windows/LogWindow.resx
new file mode 100644
index 00000000..61bc649b
--- /dev/null
+++ b/DICUI.Forms/Windows/LogWindow.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
\ No newline at end of file
diff --git a/DICUI.Forms/Windows/MainWindow.Designer.cs b/DICUI.Forms/Windows/MainWindow.Designer.cs
new file mode 100644
index 00000000..faaf6143
--- /dev/null
+++ b/DICUI.Forms/Windows/MainWindow.Designer.cs
@@ -0,0 +1,530 @@
+namespace DICUI.Forms.Windows
+{
+ partial class MainWindow
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainWindow));
+ this.MenuBar = new System.Windows.Forms.MenuStrip();
+ this.mainWindowLayout = new System.Windows.Forms.TableLayoutPanel();
+ this.settingsGroupBox = new System.Windows.Forms.GroupBox();
+ this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
+ this.parametersLabel = new System.Windows.Forms.Label();
+ this.driveSpeedLabel = new System.Windows.Forms.Label();
+ this.driveLetterLabel = new System.Windows.Forms.Label();
+ this.outputDirectoryLabel = new System.Windows.Forms.Label();
+ this.outputFilenameLabel = new System.Windows.Forms.Label();
+ this.systemMediaTypeLabel = new System.Windows.Forms.Label();
+ this.OutputFilenameTextBox = new System.Windows.Forms.TextBox();
+ this.SystemTypeComboBox = new System.Windows.Forms.ComboBox();
+ this.MediaTypeComboBox = new System.Windows.Forms.ComboBox();
+ this.OutputDirectoryTextBox = new System.Windows.Forms.TextBox();
+ this.OutputDirectoryBrowseButton = new System.Windows.Forms.Button();
+ this.DriveLetterComboBox = new System.Windows.Forms.ComboBox();
+ this.DriveSpeedComboBox = new System.Windows.Forms.ComboBox();
+ this.ParametersTextBox = new System.Windows.Forms.TextBox();
+ this.EnableParametersCheckBox = new System.Windows.Forms.CheckBox();
+ this.controlsGroupBox = new System.Windows.Forms.GroupBox();
+ this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
+ this.StartStopButton = new System.Windows.Forms.Button();
+ this.DiscScanButton = new System.Windows.Forms.Button();
+ this.CopyProtectScanButton = new System.Windows.Forms.Button();
+ this.EjectWhenDoneCheckBox = new System.Windows.Forms.CheckBox();
+ this.statusGroupBox = new System.Windows.Forms.GroupBox();
+ this.StatusLabel = new System.Windows.Forms.TextBox();
+ this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.showLogWindowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.MenuBar.SuspendLayout();
+ this.mainWindowLayout.SuspendLayout();
+ this.settingsGroupBox.SuspendLayout();
+ this.tableLayoutPanel2.SuspendLayout();
+ this.controlsGroupBox.SuspendLayout();
+ this.tableLayoutPanel3.SuspendLayout();
+ this.statusGroupBox.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // MenuBar
+ //
+ this.MenuBar.Location = new System.Drawing.Point(0, 0);
+ this.MenuBar.Name = "MenuBar";
+ this.MenuBar.Size = new System.Drawing.Size(584, 24);
+ this.MenuBar.TabIndex = 0;
+ this.MenuBar.Text = "menuStrip1";
+ this.MenuBar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ fileToolStripMenuItem, toolsToolStripMenuItem, helpToolStripMenuItem});
+ //
+ // mainWindowLayout
+ //
+ this.mainWindowLayout.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.mainWindowLayout.ColumnCount = 1;
+ this.mainWindowLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.mainWindowLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.mainWindowLayout.Controls.Add(this.settingsGroupBox, 0, 0);
+ this.mainWindowLayout.Controls.Add(this.controlsGroupBox, 0, 1);
+ this.mainWindowLayout.Controls.Add(this.statusGroupBox, 0, 2);
+ this.mainWindowLayout.Location = new System.Drawing.Point(13, 28);
+ this.mainWindowLayout.Name = "mainWindowLayout";
+ this.mainWindowLayout.RowCount = 3;
+ this.mainWindowLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 82.66254F));
+ this.mainWindowLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 17.33746F));
+ this.mainWindowLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 47F));
+ this.mainWindowLayout.Size = new System.Drawing.Size(559, 371);
+ this.mainWindowLayout.TabIndex = 1;
+ //
+ // settingsGroupBox
+ //
+ this.settingsGroupBox.Controls.Add(this.tableLayoutPanel2);
+ this.settingsGroupBox.Location = new System.Drawing.Point(3, 3);
+ this.settingsGroupBox.Name = "settingsGroupBox";
+ this.settingsGroupBox.Size = new System.Drawing.Size(553, 259);
+ this.settingsGroupBox.TabIndex = 0;
+ this.settingsGroupBox.TabStop = false;
+ this.settingsGroupBox.Text = "Settings";
+ //
+ // tableLayoutPanel2
+ //
+ this.tableLayoutPanel2.ColumnCount = 3;
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 26.32794F));
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 73.67206F));
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 144F));
+ this.tableLayoutPanel2.Controls.Add(this.parametersLabel, 0, 5);
+ this.tableLayoutPanel2.Controls.Add(this.driveSpeedLabel, 0, 4);
+ this.tableLayoutPanel2.Controls.Add(this.driveLetterLabel, 0, 3);
+ this.tableLayoutPanel2.Controls.Add(this.outputDirectoryLabel, 0, 2);
+ this.tableLayoutPanel2.Controls.Add(this.outputFilenameLabel, 0, 1);
+ this.tableLayoutPanel2.Controls.Add(this.systemMediaTypeLabel, 0, 0);
+ this.tableLayoutPanel2.Controls.Add(this.OutputFilenameTextBox, 1, 1);
+ this.tableLayoutPanel2.Controls.Add(this.SystemTypeComboBox, 1, 0);
+ this.tableLayoutPanel2.Controls.Add(this.MediaTypeComboBox, 2, 0);
+ this.tableLayoutPanel2.Controls.Add(this.OutputDirectoryTextBox, 1, 2);
+ this.tableLayoutPanel2.Controls.Add(this.OutputDirectoryBrowseButton, 2, 2);
+ this.tableLayoutPanel2.Controls.Add(this.DriveLetterComboBox, 1, 3);
+ this.tableLayoutPanel2.Controls.Add(this.DriveSpeedComboBox, 1, 4);
+ this.tableLayoutPanel2.Controls.Add(this.ParametersTextBox, 1, 5);
+ this.tableLayoutPanel2.Controls.Add(this.EnableParametersCheckBox, 2, 5);
+ this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 19);
+ this.tableLayoutPanel2.Name = "tableLayoutPanel2";
+ this.tableLayoutPanel2.Padding = new System.Windows.Forms.Padding(0, 5, 0, 5);
+ this.tableLayoutPanel2.RowCount = 6;
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tableLayoutPanel2.Size = new System.Drawing.Size(553, 234);
+ this.tableLayoutPanel2.TabIndex = 0;
+ //
+ // parametersLabel
+ //
+ this.parametersLabel.AutoSize = true;
+ this.parametersLabel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.parametersLabel.Location = new System.Drawing.Point(3, 190);
+ this.parametersLabel.Name = "parametersLabel";
+ this.parametersLabel.Size = new System.Drawing.Size(101, 39);
+ this.parametersLabel.TabIndex = 10;
+ this.parametersLabel.Text = "Parameters";
+ this.parametersLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // driveSpeedLabel
+ //
+ this.driveSpeedLabel.AutoSize = true;
+ this.driveSpeedLabel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.driveSpeedLabel.Location = new System.Drawing.Point(3, 153);
+ this.driveSpeedLabel.Name = "driveSpeedLabel";
+ this.driveSpeedLabel.Size = new System.Drawing.Size(101, 37);
+ this.driveSpeedLabel.TabIndex = 8;
+ this.driveSpeedLabel.Text = "Drive Speed";
+ this.driveSpeedLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // driveLetterLabel
+ //
+ this.driveLetterLabel.AutoSize = true;
+ this.driveLetterLabel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.driveLetterLabel.Location = new System.Drawing.Point(3, 116);
+ this.driveLetterLabel.Name = "driveLetterLabel";
+ this.driveLetterLabel.Size = new System.Drawing.Size(101, 37);
+ this.driveLetterLabel.TabIndex = 6;
+ this.driveLetterLabel.Text = "Drive Letter";
+ this.driveLetterLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // outputDirectoryLabel
+ //
+ this.outputDirectoryLabel.AutoSize = true;
+ this.outputDirectoryLabel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.outputDirectoryLabel.Location = new System.Drawing.Point(3, 79);
+ this.outputDirectoryLabel.Name = "outputDirectoryLabel";
+ this.outputDirectoryLabel.Size = new System.Drawing.Size(101, 37);
+ this.outputDirectoryLabel.TabIndex = 4;
+ this.outputDirectoryLabel.Text = "Output Directory";
+ this.outputDirectoryLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // outputFilenameLabel
+ //
+ this.outputFilenameLabel.AutoSize = true;
+ this.outputFilenameLabel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.outputFilenameLabel.Location = new System.Drawing.Point(3, 42);
+ this.outputFilenameLabel.Name = "outputFilenameLabel";
+ this.outputFilenameLabel.Size = new System.Drawing.Size(101, 37);
+ this.outputFilenameLabel.TabIndex = 2;
+ this.outputFilenameLabel.Text = "Output Filename";
+ this.outputFilenameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // systemMediaTypeLabel
+ //
+ this.systemMediaTypeLabel.AutoSize = true;
+ this.systemMediaTypeLabel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.systemMediaTypeLabel.Location = new System.Drawing.Point(3, 5);
+ this.systemMediaTypeLabel.Name = "systemMediaTypeLabel";
+ this.systemMediaTypeLabel.Size = new System.Drawing.Size(101, 37);
+ this.systemMediaTypeLabel.TabIndex = 0;
+ this.systemMediaTypeLabel.Text = "System/Media Type";
+ this.systemMediaTypeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // OutputFilenameTextBox
+ //
+ this.OutputFilenameTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.tableLayoutPanel2.SetColumnSpan(this.OutputFilenameTextBox, 2);
+ this.OutputFilenameTextBox.Location = new System.Drawing.Point(111, 50);
+ this.OutputFilenameTextBox.Name = "OutputFilenameTextBox";
+ this.OutputFilenameTextBox.Size = new System.Drawing.Size(438, 20);
+ this.OutputFilenameTextBox.TabIndex = 11;
+ this.OutputFilenameTextBox.TextChanged += new System.EventHandler(this.OutputFilenameTextBoxTextChanged);
+ //
+ // SystemTypeComboBox
+ //
+ this.SystemTypeComboBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.SystemTypeComboBox.DisplayMember = "Name";
+ this.SystemTypeComboBox.DropDownWidth = 250;
+ this.SystemTypeComboBox.FormattingEnabled = true;
+ this.SystemTypeComboBox.Location = new System.Drawing.Point(110, 13);
+ this.SystemTypeComboBox.Name = "SystemTypeComboBox";
+ this.SystemTypeComboBox.Size = new System.Drawing.Size(295, 21);
+ this.SystemTypeComboBox.TabIndex = 13;
+ this.SystemTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.SystemTypeComboBoxSelectionChanged);
+ //
+ // MediaTypeComboBox
+ //
+ this.MediaTypeComboBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.MediaTypeComboBox.DisplayMember = "Name";
+ this.MediaTypeComboBox.FormattingEnabled = true;
+ this.MediaTypeComboBox.Location = new System.Drawing.Point(415, 13);
+ this.MediaTypeComboBox.Name = "MediaTypeComboBox";
+ this.MediaTypeComboBox.Size = new System.Drawing.Size(131, 21);
+ this.MediaTypeComboBox.TabIndex = 14;
+ this.MediaTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.MediaTypeComboBoxSelectionChanged);
+ //
+ // OutputDirectoryTextBox
+ //
+ this.OutputDirectoryTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.OutputDirectoryTextBox.Location = new System.Drawing.Point(110, 87);
+ this.OutputDirectoryTextBox.Name = "OutputDirectoryTextBox";
+ this.OutputDirectoryTextBox.Size = new System.Drawing.Size(295, 20);
+ this.OutputDirectoryTextBox.TabIndex = 15;
+ this.OutputDirectoryTextBox.TextChanged += new System.EventHandler(this.OutputDirectoryTextBoxTextChanged);
+ //
+ // OutputDirectoryBrowseButton
+ //
+ this.OutputDirectoryBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
+ this.OutputDirectoryBrowseButton.Location = new System.Drawing.Point(411, 84);
+ this.OutputDirectoryBrowseButton.Name = "OutputDirectoryBrowseButton";
+ this.OutputDirectoryBrowseButton.Size = new System.Drawing.Size(139, 26);
+ this.OutputDirectoryBrowseButton.TabIndex = 16;
+ this.OutputDirectoryBrowseButton.Text = "Browse";
+ this.OutputDirectoryBrowseButton.UseVisualStyleBackColor = true;
+ this.OutputDirectoryBrowseButton.Click += new System.EventHandler(this.OutputDirectoryBrowseButtonClick);
+ //
+ // DriveLetterComboBox
+ //
+ this.DriveLetterComboBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.DriveLetterComboBox.DisplayMember = "Letter";
+ this.DriveLetterComboBox.FormattingEnabled = true;
+ this.DriveLetterComboBox.Location = new System.Drawing.Point(110, 124);
+ this.DriveLetterComboBox.Name = "DriveLetterComboBox";
+ this.DriveLetterComboBox.Size = new System.Drawing.Size(121, 21);
+ this.DriveLetterComboBox.TabIndex = 17;
+ this.DriveLetterComboBox.SelectedIndexChanged += new System.EventHandler(this.DriveLetterComboBoxSelectionChanged);
+ //
+ // DriveSpeedComboBox
+ //
+ this.DriveSpeedComboBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.DriveSpeedComboBox.FormattingEnabled = true;
+ this.DriveSpeedComboBox.Location = new System.Drawing.Point(110, 161);
+ this.DriveSpeedComboBox.Name = "DriveSpeedComboBox";
+ this.DriveSpeedComboBox.Size = new System.Drawing.Size(121, 21);
+ this.DriveSpeedComboBox.TabIndex = 18;
+ this.DriveSpeedComboBox.SelectedIndexChanged += new System.EventHandler(this.DriveSpeedComboBoxSelectionChanged);
+ //
+ // ParametersTextBox
+ //
+ this.ParametersTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.ParametersTextBox.Enabled = false;
+ this.ParametersTextBox.Location = new System.Drawing.Point(110, 199);
+ this.ParametersTextBox.Name = "ParametersTextBox";
+ this.ParametersTextBox.ReadOnly = true;
+ this.ParametersTextBox.Size = new System.Drawing.Size(295, 20);
+ this.ParametersTextBox.TabIndex = 19;
+ //
+ // EnableParametersCheckBox
+ //
+ this.EnableParametersCheckBox.AutoSize = true;
+ this.EnableParametersCheckBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.EnableParametersCheckBox.Location = new System.Drawing.Point(411, 193);
+ this.EnableParametersCheckBox.Name = "EnableParametersCheckBox";
+ this.EnableParametersCheckBox.Size = new System.Drawing.Size(139, 33);
+ this.EnableParametersCheckBox.TabIndex = 20;
+ this.EnableParametersCheckBox.Text = "Enable Editing";
+ this.EnableParametersCheckBox.UseVisualStyleBackColor = true;
+ this.EnableParametersCheckBox.CheckedChanged += new System.EventHandler(this.EnableParametersCheckBoxClick);
+ //
+ // controlsGroupBox
+ //
+ this.controlsGroupBox.Controls.Add(this.tableLayoutPanel3);
+ this.controlsGroupBox.Location = new System.Drawing.Point(3, 270);
+ this.controlsGroupBox.Name = "controlsGroupBox";
+ this.controlsGroupBox.Size = new System.Drawing.Size(553, 50);
+ this.controlsGroupBox.TabIndex = 1;
+ this.controlsGroupBox.TabStop = false;
+ this.controlsGroupBox.Text = "Controls";
+ //
+ // tableLayoutPanel3
+ //
+ this.tableLayoutPanel3.ColumnCount = 4;
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
+ this.tableLayoutPanel3.Controls.Add(this.StartStopButton, 0, 0);
+ this.tableLayoutPanel3.Controls.Add(this.DiscScanButton, 1, 0);
+ this.tableLayoutPanel3.Controls.Add(this.CopyProtectScanButton, 2, 0);
+ this.tableLayoutPanel3.Controls.Add(this.EjectWhenDoneCheckBox, 3, 0);
+ this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 20);
+ this.tableLayoutPanel3.Name = "tableLayoutPanel3";
+ this.tableLayoutPanel3.RowCount = 1;
+ this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel3.Size = new System.Drawing.Size(553, 32);
+ this.tableLayoutPanel3.TabIndex = 0;
+ //
+ // StartStopButton
+ //
+ this.StartStopButton.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.StartStopButton.Enabled = false;
+ this.StartStopButton.Location = new System.Drawing.Point(3, 3);
+ this.StartStopButton.Name = "StartStopButton";
+ this.StartStopButton.Size = new System.Drawing.Size(132, 26);
+ this.StartStopButton.TabIndex = 0;
+ this.StartStopButton.Text = "Start Dumping";
+ this.StartStopButton.UseVisualStyleBackColor = true;
+ this.StartStopButton.Click += new System.EventHandler(this.StartStopButtonClick);
+ //
+ // DiscScanButton
+ //
+ this.DiscScanButton.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.DiscScanButton.Location = new System.Drawing.Point(141, 3);
+ this.DiscScanButton.Name = "DiscScanButton";
+ this.DiscScanButton.Size = new System.Drawing.Size(132, 26);
+ this.DiscScanButton.TabIndex = 1;
+ this.DiscScanButton.Text = "Scan For Discs";
+ this.DiscScanButton.UseVisualStyleBackColor = true;
+ this.DiscScanButton.Click += new System.EventHandler(this.DiscScanButtonClick);
+ //
+ // CopyProtectScanButton
+ //
+ this.CopyProtectScanButton.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.CopyProtectScanButton.Location = new System.Drawing.Point(279, 3);
+ this.CopyProtectScanButton.Name = "CopyProtectScanButton";
+ this.CopyProtectScanButton.Size = new System.Drawing.Size(132, 26);
+ this.CopyProtectScanButton.TabIndex = 2;
+ this.CopyProtectScanButton.Text = "Scan For Protection";
+ this.CopyProtectScanButton.UseVisualStyleBackColor = true;
+ this.CopyProtectScanButton.Click += new System.EventHandler(this.CopyProtectScanButtonClick);
+ //
+ // EjectWhenDoneCheckBox
+ //
+ this.EjectWhenDoneCheckBox.AutoSize = true;
+ this.EjectWhenDoneCheckBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.EjectWhenDoneCheckBox.Location = new System.Drawing.Point(417, 3);
+ this.EjectWhenDoneCheckBox.Name = "EjectWhenDoneCheckBox";
+ this.EjectWhenDoneCheckBox.Size = new System.Drawing.Size(133, 26);
+ this.EjectWhenDoneCheckBox.TabIndex = 3;
+ this.EjectWhenDoneCheckBox.Text = "Eject When Done";
+ this.EjectWhenDoneCheckBox.UseVisualStyleBackColor = true;
+ //
+ // statusGroupBox
+ //
+ this.statusGroupBox.Controls.Add(this.StatusLabel);
+ this.statusGroupBox.Location = new System.Drawing.Point(3, 326);
+ this.statusGroupBox.Name = "statusGroupBox";
+ this.statusGroupBox.Size = new System.Drawing.Size(553, 42);
+ this.statusGroupBox.TabIndex = 2;
+ this.statusGroupBox.TabStop = false;
+ this.statusGroupBox.Text = "Status";
+ //
+ // StatusLabel
+ //
+ this.StatusLabel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.StatusLabel.Enabled = false;
+ this.StatusLabel.Location = new System.Drawing.Point(3, 16);
+ this.StatusLabel.Name = "StatusLabel";
+ this.StatusLabel.ReadOnly = true;
+ this.StatusLabel.Size = new System.Drawing.Size(547, 20);
+ this.StatusLabel.TabIndex = 0;
+ this.StatusLabel.Text = "Waiting for media...";
+ this.StatusLabel.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
+ //
+ // fileToolStripMenuItem
+ //
+ this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
+ this.fileToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F)));
+ this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
+ this.fileToolStripMenuItem.Text = "File";
+ //
+ // toolsToolStripMenuItem
+ //
+ this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
+ this.toolsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.T)));
+ this.toolsToolStripMenuItem.Size = new System.Drawing.Size(47, 20);
+ this.toolsToolStripMenuItem.Text = "Tools";
+ //
+ // helpToolStripMenuItem
+ //
+ this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
+ this.helpToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.H)));
+ this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
+ this.helpToolStripMenuItem.Text = "Help";
+ //
+ // exitToolStripMenuItem
+ //
+ this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
+ this.exitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.X)));
+ this.exitToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.exitToolStripMenuItem.Text = "Exit";
+ this.exitToolStripMenuItem.Click += new System.EventHandler(this.AppExitClick);
+ //
+ // optionsToolStripMenuItem
+ //
+ this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
+ this.optionsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.O)));
+ this.optionsToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
+ this.optionsToolStripMenuItem.Text = "Options";
+ this.optionsToolStripMenuItem.Click += new System.EventHandler(this.OptionsClick);
+ //
+ // showLogWindowToolStripMenuItem
+ //
+ this.showLogWindowToolStripMenuItem.Checked = true;
+ this.showLogWindowToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.showLogWindowToolStripMenuItem.Name = "showLogWindowToolStripMenuItem";
+ this.showLogWindowToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.L)));
+ this.showLogWindowToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
+ this.showLogWindowToolStripMenuItem.Text = "Show Log Window";
+ //
+ // aboutToolStripMenuItem
+ //
+ this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
+ this.aboutToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.A)));
+ this.aboutToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.aboutToolStripMenuItem.Text = "About";
+ this.aboutToolStripMenuItem.Click += new System.EventHandler(this.AboutClick);
+ //
+ // MainWindow
+ //
+ this.AcceptButton = this.StartStopButton;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(584, 411);
+ this.Controls.Add(this.mainWindowLayout);
+ this.Controls.Add(this.MenuBar);
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.MainMenuStrip = this.MenuBar;
+ this.Name = "MainWindow";
+ this.Text = "DiscImageCreator GUI";
+ this.Activated += new System.EventHandler(this.MainWindowActivated);
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainWindowClosing);
+ this.Load += new System.EventHandler(this.OnContentRendered);
+ this.LocationChanged += new System.EventHandler(this.MainWindowLocationChanged);
+ this.MenuBar.ResumeLayout(false);
+ this.MenuBar.PerformLayout();
+ this.mainWindowLayout.ResumeLayout(false);
+ this.settingsGroupBox.ResumeLayout(false);
+ this.tableLayoutPanel2.ResumeLayout(false);
+ this.tableLayoutPanel2.PerformLayout();
+ this.controlsGroupBox.ResumeLayout(false);
+ this.tableLayoutPanel3.ResumeLayout(false);
+ this.tableLayoutPanel3.PerformLayout();
+ this.statusGroupBox.ResumeLayout(false);
+ this.statusGroupBox.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.MenuStrip MenuBar;
+ private System.Windows.Forms.TableLayoutPanel mainWindowLayout;
+ private System.Windows.Forms.GroupBox settingsGroupBox;
+ private System.Windows.Forms.GroupBox controlsGroupBox;
+ private System.Windows.Forms.GroupBox statusGroupBox;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
+ private System.Windows.Forms.Label systemMediaTypeLabel;
+ private System.Windows.Forms.Label parametersLabel;
+ private System.Windows.Forms.Label driveSpeedLabel;
+ private System.Windows.Forms.Label driveLetterLabel;
+ private System.Windows.Forms.Label outputDirectoryLabel;
+ private System.Windows.Forms.Label outputFilenameLabel;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
+ private System.Windows.Forms.Button StartStopButton;
+ private System.Windows.Forms.Button DiscScanButton;
+ private System.Windows.Forms.Button CopyProtectScanButton;
+ private System.Windows.Forms.CheckBox EjectWhenDoneCheckBox;
+ private System.Windows.Forms.TextBox OutputFilenameTextBox;
+ private System.Windows.Forms.ComboBox SystemTypeComboBox;
+ private System.Windows.Forms.ComboBox MediaTypeComboBox;
+ private System.Windows.Forms.TextBox OutputDirectoryTextBox;
+ private System.Windows.Forms.Button OutputDirectoryBrowseButton;
+ private System.Windows.Forms.ComboBox DriveLetterComboBox;
+ private System.Windows.Forms.ComboBox DriveSpeedComboBox;
+ private System.Windows.Forms.TextBox ParametersTextBox;
+ private System.Windows.Forms.CheckBox EnableParametersCheckBox;
+ private System.Windows.Forms.TextBox StatusLabel;
+ private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem;
+ internal System.Windows.Forms.ToolStripMenuItem showLogWindowToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
+ }
+}
+
diff --git a/DICUI.Forms/Windows/MainWindow.cs b/DICUI.Forms/Windows/MainWindow.cs
new file mode 100644
index 00000000..6db59218
--- /dev/null
+++ b/DICUI.Forms/Windows/MainWindow.cs
@@ -0,0 +1,723 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Forms;
+using DICUI.Data;
+using DICUI.Utilities;
+
+namespace DICUI.Forms.Windows
+{
+ public partial class MainWindow : Form
+ {
+ // Private UI-related variables
+ private List _drives;
+ private MediaType? _currentMediaType;
+ private List _systems;
+ private List _mediaTypes;
+ private bool _alreadyShown;
+
+ private DumpEnvironment _env;
+
+ // Option related
+ private Options _options;
+ private OptionsWindow _optionsWindow;
+
+ private LogWindow _logWindow;
+
+ public MainWindow()
+ {
+ InitializeComponent();
+
+ // Initializes and load Options object
+ _options = new Options();
+ _options.Load();
+ ViewModels.OptionsViewModel = new OptionsViewModel(_options);
+
+ _logWindow = new LogWindow(this);
+ ViewModels.LoggerViewModel.SetWindow(_logWindow);
+
+ // Disable buttons until we load fully
+ StartStopButton.Enabled = false;
+ DiscScanButton.Enabled = false;
+ CopyProtectScanButton.Enabled = false;
+
+ if (_options.OpenLogWindowAtStartup)
+ {
+ this.StartPosition = FormStartPosition.CenterScreen;
+ double combinedHeight = this.Height + _logWindow.Height + Constants.LogWindowMarginFromMainWindow;
+ Rectangle bounds = GetScaledCoordinates(Screen.PrimaryScreen.WorkingArea);
+
+ this.Left = (int)(bounds.Left + (bounds.Width - this.Width) / 2);
+ this.Top = (int)(bounds.Top + (bounds.Height - combinedHeight) / 2);
+ }
+ }
+
+ #region Events
+
+ private void OnContentRendered(object sender, EventArgs e)
+ {
+ if (_alreadyShown)
+ return;
+
+ _alreadyShown = true;
+
+ if (_options.OpenLogWindowAtStartup)
+ {
+ //TODO: this should be bound directly to WindowVisible property in two way fashion
+ // we need to study how to properly do it in XAML
+ showLogWindowToolStripMenuItem.Checked = true;
+ ViewModels.LoggerViewModel.WindowVisible = true;
+ }
+
+ // Populate the list of systems
+ StatusLabel.Text = "Creating system list, please wait!";
+ PopulateSystems();
+
+ // Populate the list of drives
+ StatusLabel.Text = "Creating drive list, please wait!";
+ PopulateDrives();
+
+ // Set the position of the log window
+ if (_logWindow.Visible)
+ {
+ _logWindow.AdjustPositionToMainWindow();
+ this.Focus();
+ }
+ }
+
+ private void StartStopButtonClick(object sender, EventArgs e)
+ {
+ // Dump or stop the dump
+ if (StartStopButton.Text == Constants.StartDumping)
+ {
+ StartDumping();
+ }
+ else if (StartStopButton.Text == Constants.StopDumping)
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn("Canceling dumping process...");
+ _env.CancelDumping();
+ CopyProtectScanButton.Enabled = true;
+
+ if (EjectWhenDoneCheckBox.Checked == true)
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
+ _env.EjectDisc();
+ }
+ }
+ }
+
+ private void OutputDirectoryBrowseButtonClick(object sender, EventArgs e)
+ {
+ BrowseFolder();
+ EnsureDiscInformation();
+ }
+
+ private void DiscScanButtonClick(object sender, EventArgs e)
+ {
+ PopulateDrives();
+ }
+
+ private void CopyProtectScanButtonClick(object sender, EventArgs e)
+ {
+ ScanAndShowProtection();
+ }
+
+ private void SystemTypeComboBoxSelectionChanged(object sender, EventArgs e)
+ {
+ // If we're on a separator, go to the next item and return
+ if ((SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem).IsHeader())
+ {
+ SystemTypeComboBox.SelectedIndex++;
+ return;
+ }
+
+ ViewModels.LoggerViewModel.VerboseLogLn("Changed system to: {0}", (SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem).Name);
+ PopulateMediaType();
+ EnsureDiscInformation();
+ }
+
+ private void MediaTypeComboBoxSelectionChanged(object sender, EventArgs e)
+ {
+ _currentMediaType = MediaTypeComboBox.SelectedItem as MediaType?;
+ SetSupportedDriveSpeed();
+ GetOutputNames();
+ EnsureDiscInformation();
+ }
+
+ private void DriveLetterComboBoxSelectionChanged(object sender, EventArgs e)
+ {
+ CacheCurrentDiscType();
+ SetCurrentDiscType();
+ GetOutputNames();
+ SetSupportedDriveSpeed();
+ }
+
+ private void DriveSpeedComboBoxSelectionChanged(object sender, EventArgs e)
+ {
+ EnsureDiscInformation();
+ }
+
+ private void OutputFilenameTextBoxTextChanged(object sender, EventArgs e)
+ {
+ EnsureDiscInformation();
+ }
+
+ private void OutputDirectoryTextBoxTextChanged(object sender, EventArgs e)
+ {
+ EnsureDiscInformation();
+ }
+
+ private void ProgressUpdated(object sender, Result value)
+ {
+ StatusLabel.Text = value.Message;
+ ViewModels.LoggerViewModel.VerboseLogLn(value.Message);
+ }
+
+ private void MainWindowLocationChanged(object sender, EventArgs e)
+ {
+ if (_logWindow.Visible)
+ _logWindow.AdjustPositionToMainWindow();
+ }
+
+ private void MainWindowActivated(object sender, EventArgs e)
+ {
+ if (!_logWindow.Visible)
+ _logWindow.BringToFront();
+ this.BringToFront();
+ }
+
+ private void MainWindowClosing(object sender, FormClosingEventArgs e)
+ {
+ if (_logWindow.Visible)
+ _logWindow.Close();
+ }
+
+ private void EnableParametersCheckBoxClick(object sender, EventArgs e)
+ {
+ if (EnableParametersCheckBox.Checked)
+ {
+ ParametersTextBox.ReadOnly = false;
+ ParametersTextBox.Enabled = true;
+ }
+ else
+ {
+ ParametersTextBox.ReadOnly = true;
+ ParametersTextBox.Enabled = false;
+ ProcessCustomParameters();
+ }
+ }
+
+ // Toolbar Events
+
+ private void AppExitClick(object sender, EventArgs e)
+ {
+ System.Windows.Application.Current.Shutdown();
+ }
+
+ private void AboutClick(object sender, EventArgs e)
+ {
+ System.Windows.MessageBox.Show($"ReignStumble - Project Lead / UI Design{Environment.NewLine}" +
+ $"darksabre76 - Project Co-Lead / Backend Design{Environment.NewLine}" +
+ $"Jakz - Feature Contributor{Environment.NewLine}" +
+ $"NHellFire - Feature Contributor{Environment.NewLine}" +
+ $"Dizzzy - Concept/Ideas/Beta tester{Environment.NewLine}", "About", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+
+ private void OptionsClick(object sender, EventArgs e)
+ {
+ // lazy initialization
+ if (_optionsWindow == null)
+ {
+ _optionsWindow = new OptionsWindow(this, _options);
+ _optionsWindow.Closed += delegate
+ {
+ _optionsWindow = null;
+ };
+ }
+
+ _optionsWindow.Owner = this;
+ _optionsWindow.StartPosition = FormStartPosition.CenterParent;
+ _optionsWindow.RefreshSettings();
+ _optionsWindow.Show();
+ }
+
+ public void OnOptionsUpdated()
+ {
+ GetOutputNames();
+ SetSupportedDriveSpeed();
+ EnsureDiscInformation();
+ }
+
+ #endregion
+
+ #region Helpers
+
+ ///
+ /// Populate media type according to system type
+ ///
+ private void PopulateMediaType()
+ {
+ KnownSystem? currentSystem = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem;
+
+ if (currentSystem != null)
+ {
+ _mediaTypes = Validators.GetValidMediaTypes(currentSystem).ToList();
+ MediaTypeComboBox.DataSource = _mediaTypes;
+
+ MediaTypeComboBox.Enabled = _mediaTypes.Count > 1;
+ MediaTypeComboBox.SelectedIndex = (_mediaTypes.IndexOf(_currentMediaType) >= 0 ? _mediaTypes.IndexOf(_currentMediaType) : 0);
+ }
+ else
+ {
+ MediaTypeComboBox.Enabled = false;
+ MediaTypeComboBox.DataSource = null;
+ MediaTypeComboBox.SelectedIndex = -1;
+ }
+ }
+
+ ///
+ /// Get a complete list of supported systems and fill the combo box
+ ///
+ private void PopulateSystems()
+ {
+ _systems = Validators.CreateListOfSystems();
+
+ ViewModels.LoggerViewModel.VerboseLogLn("Populating systems, {0} systems found.", _systems.Count);
+
+ Dictionary> mapping = _systems
+ .GroupBy(s => s.Category())
+ .ToDictionary(
+ k => k.Key,
+ v => v
+ .OrderBy(s => s.Name())
+ .ToList()
+ );
+
+ List comboBoxItems = new List();
+
+ comboBoxItems.Add(new KnownSystemComboBoxItem(KnownSystem.NONE));
+
+ foreach (var group in mapping)
+ {
+ comboBoxItems.Add(new KnownSystemComboBoxItem(group.Key));
+ group.Value.ForEach(system => comboBoxItems.Add(new KnownSystemComboBoxItem(system)));
+ }
+
+ SystemTypeComboBox.DataSource = comboBoxItems;
+ SystemTypeComboBox.SelectedIndex = 0;
+
+ StartStopButton.Enabled = false;
+ }
+
+ ///
+ /// Get a complete list of active disc drives and fill the combo box
+ ///
+ /// TODO: Find a way for this to periodically run, or have it hook to a "drive change" event
+ private void PopulateDrives()
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn("Scanning for drives..");
+
+ // Always enable the disk scan
+ DiscScanButton.Enabled = true;
+
+ // Populate the list of drives and add it to the combo box
+ _drives = Validators.CreateListOfDrives();
+ DriveLetterComboBox.DataSource = _drives;
+
+ if (DriveLetterComboBox.Items.Count > 0)
+ {
+ int index = _drives.FindIndex(d => d.MarkedActive);
+ DriveLetterComboBox.SelectedIndex = (index != -1 ? index : 0);
+ StatusLabel.Text = "Valid drive found! Choose your Media Type";
+ StartStopButton.Enabled = true;
+ CopyProtectScanButton.Enabled = true;
+
+ ViewModels.LoggerViewModel.VerboseLogLn("Found {0} drives: {1}", _drives.Count, String.Join(", ", _drives.Select(d => d.Letter)));
+ }
+ else
+ {
+ DriveLetterComboBox.SelectedIndex = -1;
+ StatusLabel.Text = "No valid drive found!";
+ StartStopButton.Enabled = false;
+ CopyProtectScanButton.Enabled = false;
+
+ ViewModels.LoggerViewModel.VerboseLogLn("Found no drives");
+ }
+ }
+
+ ///
+ /// Browse for an output folder
+ ///
+ private void BrowseFolder()
+ {
+ FolderBrowserDialog folderDialog = new FolderBrowserDialog { ShowNewFolderButton = false, SelectedPath = System.AppDomain.CurrentDomain.BaseDirectory };
+ DialogResult result = folderDialog.ShowDialog();
+
+ if (result == DialogResult.OK)
+ {
+ OutputDirectoryTextBox.Text = folderDialog.SelectedPath;
+ }
+ }
+
+ ///
+ /// Create a DumpEnvironment with all current settings
+ ///
+ /// Filled DumpEnvironment instance
+ private DumpEnvironment DetermineEnvironment()
+ {
+ // Populate the new environment
+ var env = new DumpEnvironment()
+ {
+ // Paths to tools
+ SubdumpPath = _options.SubDumpPath,
+ DICPath = _options.DICPath,
+
+ OutputDirectory = OutputDirectoryTextBox.Text,
+ OutputFilename = OutputFilenameTextBox.Text,
+
+ // Get the currently selected options
+ Drive = DriveLetterComboBox.SelectedItem as Drive,
+
+ DICParameters = new Parameters(ParametersTextBox.Text),
+
+ QuietMode = _options.QuietMode,
+ ParanoidMode = _options.ParanoidMode,
+ ScanForProtection = _options.ScanForProtection,
+ RereadAmountC2 = _options.RereadAmountForC2,
+
+ System = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem,
+ Type = MediaTypeComboBox.SelectedItem as MediaType?
+ };
+
+ // Fix the output paths
+ env.FixOutputPaths();
+
+ // Disable automatic reprocessing of the textboxes until we're done
+ OutputDirectoryTextBox.TextChanged -= OutputDirectoryTextBoxTextChanged;
+ OutputFilenameTextBox.TextChanged -= OutputFilenameTextBoxTextChanged;
+
+ OutputDirectoryTextBox.Text = env.OutputDirectory;
+ OutputFilenameTextBox.Text = env.OutputFilename;
+
+ OutputDirectoryTextBox.TextChanged += OutputDirectoryTextBoxTextChanged;
+ OutputFilenameTextBox.TextChanged += OutputFilenameTextBoxTextChanged;
+
+ return env;
+ }
+
+ ///
+ /// Begin the dumping process using the given inputs
+ ///
+ private async void StartDumping()
+ {
+ if (_env == null)
+ _env = DetermineEnvironment();
+
+ // If still in custom parameter mode, check that users meant to continue or not
+ if (EnableParametersCheckBox.Checked == true)
+ {
+ MessageBoxResult result = System.Windows.MessageBox.Show("It looks like you have custom parameters that have not been saved. Would you like to apply those changes before starting to dump?", "Custom Changes", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
+ if (result == MessageBoxResult.Yes)
+ {
+ EnableParametersCheckBox.Checked = false;
+ ParametersTextBox.Enabled = false;
+ ProcessCustomParameters();
+ }
+ else if (result == MessageBoxResult.Cancel)
+ return;
+ // If "No", then we continue with the current known environment
+ }
+
+ try
+ {
+ // Check for the firmware first
+ // TODO: Remove this (and method) once DIC end-to-end logging becomes a thing
+ if (!await _env.DriveHasLatestFimrware())
+ {
+ System.Windows.MessageBox.Show($"DiscImageCreator has reported that drive {_env.Drive.Letter} is not updated to the most recent firmware. Please update the firmware for your drive and try again.", "Outdated Firmware", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ // Validate that the user explicitly wants an inactive drive to be considered for dumping
+ if (!_env.Drive.MarkedActive)
+ {
+ MessageBoxResult mbresult = System.Windows.MessageBox.Show("The currently selected drive does not appear to contain a disc! Are you sure you want to continue?", "Missing Disc", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
+ if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel || mbresult == MessageBoxResult.None)
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn("Dumping aborted!");
+ return;
+ }
+ }
+
+ // If a complete dump already exists
+ if (_env.FoundAllFiles())
+ {
+ MessageBoxResult mbresult = System.Windows.MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
+ if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel || mbresult == MessageBoxResult.None)
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn("Dumping aborted!");
+ return;
+ }
+ }
+
+ StartStopButton.Text = Constants.StopDumping;
+ CopyProtectScanButton.Enabled = false;
+ StatusLabel.Text = "Beginning dumping process";
+ ViewModels.LoggerViewModel.VerboseLogLn("Starting dumping process..");
+
+ var progress = new Progress();
+ progress.ProgressChanged += ProgressUpdated;
+ Result result = await _env.StartDumping(progress);
+
+ StatusLabel.Text = result ? "Dumping complete!" : result.Message;
+ ViewModels.LoggerViewModel.VerboseLogLn(result ? "Dumping complete!" : result.Message);
+ }
+ catch
+ {
+ // No-op, we don't care what it was
+ }
+ finally
+ {
+ StartStopButton.Text = Constants.StartDumping;
+ CopyProtectScanButton.Enabled = true;
+ }
+
+ if (EjectWhenDoneCheckBox.Checked == true)
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
+ _env.EjectDisc();
+ }
+ }
+
+ ///
+ /// Ensure information is consistent with the currently selected disc type
+ ///
+ private void EnsureDiscInformation()
+ {
+ // Get the current environment information
+ _env = DetermineEnvironment();
+
+ // Take care of null cases
+ if (_env.System == null)
+ _env.System = KnownSystem.NONE;
+ if (_env.Type == null)
+ _env.Type = MediaType.NONE;
+
+ // Get the status to write out
+ Result result = Validators.GetSupportStatus(_env.System, _env.Type);
+ StatusLabel.Text = result.Message;
+
+ // Set the index for the current disc type
+ SetCurrentDiscType();
+
+ StartStopButton.Enabled = result && (_drives != null && _drives.Count > 0 ? true : false);
+
+ // If we're in a type that doesn't support drive speeds
+ DriveSpeedComboBox.Enabled = _env.Type.DoesSupportDriveSpeed();
+
+ // If input params are not enabled, generate the full parameters from the environment
+ if (!ParametersTextBox.Enabled)
+ {
+ string generated = _env.GetFullParameters((int?)DriveSpeedComboBox.SelectedItem);
+ if (generated != null)
+ ParametersTextBox.Text = generated;
+ }
+ }
+
+ ///
+ /// Get the default output directory name from the currently selected drive
+ ///
+ private void GetOutputNames()
+ {
+ Drive drive = DriveLetterComboBox.SelectedItem as Drive;
+ KnownSystem? systemType = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem;
+ MediaType? mediaType = MediaTypeComboBox.SelectedItem as MediaType?;
+
+ OutputDirectoryTextBox.Text = Path.Combine(_options.DefaultOutputPath, drive?.VolumeLabel ?? string.Empty);
+ OutputFilenameTextBox.Text = (drive?.VolumeLabel ?? "disc") + (mediaType.Extension() ?? ".bin");
+ }
+
+ ///
+ /// Scan and show copy protection for the current disc
+ ///
+ private async void ScanAndShowProtection()
+ {
+ if (_env == null)
+ _env = DetermineEnvironment();
+
+ if (_env.Drive.Letter != default(char))
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn("Scanning for copy protection in {0}", _env.Drive.Letter);
+
+ var tempContent = StatusLabel.Text;
+ StatusLabel.Text = "Scanning for copy protection... this might take a while!";
+ StartStopButton.Enabled = false;
+ DiscScanButton.Enabled = false;
+ CopyProtectScanButton.Enabled = false;
+
+ string protections = await Validators.RunProtectionScanOnPath(_env.Drive.Letter + ":\\");
+ if (!ViewModels.LoggerViewModel.WindowVisible)
+ System.Windows.MessageBox.Show(protections, "Detected Protection", MessageBoxButton.OK, MessageBoxImage.Information);
+ ViewModels.LoggerViewModel.VerboseLog("Detected the following protections in {0}:\r\n\r\n{1}", _env.Drive.Letter, protections);
+
+ StatusLabel.Text = tempContent;
+ StartStopButton.Enabled = true;
+ DiscScanButton.Enabled = true;
+ CopyProtectScanButton.Enabled = true;
+ }
+ }
+
+ ///
+ /// Set the drive speed based on reported maximum and user-defined option
+ ///
+ private void SetSupportedDriveSpeed()
+ {
+ // Set the drive speed list that's appropriate
+ var values = Constants.GetSpeedsForMediaType(_currentMediaType);
+ DriveSpeedComboBox.DataSource = values;
+ ViewModels.LoggerViewModel.VerboseLogLn("Supported media speeds: {0}", string.Join(",", values));
+
+ // Find the minimum set to compare against
+ int preferred = 100;
+ switch (_currentMediaType)
+ {
+ case MediaType.CDROM:
+ case MediaType.GDROM:
+ preferred = _options.preferredDumpSpeedCD;
+ break;
+ case MediaType.DVD:
+ case MediaType.HDDVD:
+ case MediaType.NintendoGameCube:
+ case MediaType.NintendoWiiOpticalDisc:
+ preferred = _options.preferredDumpSpeedDVD;
+ break;
+ case MediaType.BluRay:
+ preferred = _options.preferredDumpSpeedBD;
+ break;
+ default:
+ preferred = _options.preferredDumpSpeedCD;
+ break;
+ }
+
+ // Choose the lower of the two speeds between the allowed speeds and the user-defined one
+ // TODO: Inform more users about setting preferences in the settings so this comparison doesn't need to happen
+ int chosenSpeed = Math.Min(
+ values.Where(s => s <= values[values.Count / 2]).Last(),
+ preferred
+ );
+
+ // Set the selected speed
+ ViewModels.LoggerViewModel.VerboseLogLn("Setting drive speed to: {0}", chosenSpeed);
+ DriveSpeedComboBox.SelectedIndex = values.ToList().IndexOf(chosenSpeed);
+ }
+
+ ///
+ /// Cache the current disc type to internal variable
+ ///
+ private void CacheCurrentDiscType()
+ {
+ // Get the drive letter from the selected item
+ Drive drive = DriveLetterComboBox.SelectedItem as Drive;
+ if (drive == null || drive.IsFloppy)
+ return;
+
+ // Get the current optical disc type
+ if (!_options.SkipMediaTypeDetection)
+ {
+ ViewModels.LoggerViewModel.VerboseLog("Trying to detect media type for drive {0}.. ", drive.Letter);
+ _currentMediaType = Validators.GetDiscType(drive.Letter);
+ ViewModels.LoggerViewModel.VerboseLogLn(_currentMediaType != null ? "unable to detect." : ("detected " + _currentMediaType.Name() + "."));
+ }
+ }
+
+ ///
+ /// Set the current disc type in the combo box
+ ///
+ private void SetCurrentDiscType()
+ {
+ // If we have an invalid current type, we don't care and return
+ if (_currentMediaType == null || _currentMediaType == MediaType.NONE)
+ return;
+
+ // Now set the selected item, if possible
+ int index = _mediaTypes.FindIndex(kvp => kvp.Value == _currentMediaType);
+ if (index != -1)
+ MediaTypeComboBox.SelectedIndex = index;
+ else
+ StatusLabel.Text = $"Disc of type '{Converters.MediaTypeToString(_currentMediaType)}' found, but the current system does not support it!";
+ }
+
+ ///
+ /// Process the current custom parameters back into UI values
+ ///
+ private void ProcessCustomParameters()
+ {
+ _env.DICParameters = new Parameters(ParametersTextBox.Text);
+
+ int driveIndex = _drives.Select(d => d.Letter).ToList().IndexOf(_env.DICParameters.DriveLetter[0]);
+ if (driveIndex > -1)
+ DriveLetterComboBox.SelectedIndex = driveIndex;
+
+ int driveSpeed = _env.DICParameters.DriveSpeed ?? -1;
+ if (driveSpeed > 0)
+ DriveSpeedComboBox.SelectedIndex = ((IReadOnlyList)(DriveSpeedComboBox.DataSource)).ToList().IndexOf(driveSpeed);
+ else
+ _env.DICParameters.DriveSpeed = (int?)DriveSpeedComboBox.SelectedValue;
+
+ string trimmedPath = _env.DICParameters.Filename?.Trim('"') ?? string.Empty;
+ string outputDirectory = Path.GetDirectoryName(trimmedPath);
+ string outputFilename = Path.GetFileName(trimmedPath);
+ if (!String.IsNullOrWhiteSpace(outputDirectory))
+ OutputDirectoryTextBox.Text = outputDirectory;
+ else
+ outputDirectory = OutputDirectoryTextBox.Text;
+ if (!String.IsNullOrWhiteSpace(outputFilename))
+ OutputFilenameTextBox.Text = outputFilename;
+ else
+ outputFilename = OutputFilenameTextBox.Text;
+
+ MediaType? mediaType = Converters.BaseCommmandToMediaType(_env.DICParameters.Command);
+ int mediaTypeIndex = _mediaTypes.IndexOf(mediaType);
+ if (mediaTypeIndex > -1)
+ MediaTypeComboBox.SelectedIndex = mediaTypeIndex;
+ }
+
+ #endregion
+
+ #region UI Helpers
+
+ ///
+ /// Get pixel coordinates based on DPI scaling
+ ///
+ /// Rectangle representing the bounds to transform
+ /// Rectangle representing the scaled bounds
+ private Rectangle GetScaledCoordinates(Rectangle bounds)
+ {
+ using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
+ {
+ return new Rectangle(
+ TransformCoordinate(bounds.Left, g.DpiX),
+ TransformCoordinate(bounds.Top, g.DpiY),
+ TransformCoordinate(bounds.Width, g.DpiX),
+ TransformCoordinate(bounds.Height, g.DpiY));
+ }
+ }
+
+ ///
+ /// Transform an individual coordinate using DPI scaling
+ ///
+ /// Current integer coordinate
+ /// DPI scaling factor
+ /// Scaled integer coordinate
+ private int TransformCoordinate(int coord, float dpi)
+ {
+ return (int)(coord / ((double)dpi / 96));
+ }
+
+ #endregion
+ }
+}
diff --git a/DICUI.Forms/Windows/MainWindow.resx b/DICUI.Forms/Windows/MainWindow.resx
new file mode 100644
index 00000000..a9219137
--- /dev/null
+++ b/DICUI.Forms/Windows/MainWindow.resx
@@ -0,0 +1,1395 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ 84
+
+
+
+
+ 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
+
+
+
\ No newline at end of file
diff --git a/DICUI.Forms/Windows/OptionsWindow.Designer.cs b/DICUI.Forms/Windows/OptionsWindow.Designer.cs
new file mode 100644
index 00000000..8f5aeec4
--- /dev/null
+++ b/DICUI.Forms/Windows/OptionsWindow.Designer.cs
@@ -0,0 +1,565 @@
+namespace DICUI.Forms.Windows
+{
+ partial class OptionsWindow
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
+ this.pathsGroupBox = new System.Windows.Forms.GroupBox();
+ this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
+ this.DefaultOutputPathButton = new System.Windows.Forms.Button();
+ this.SubDumpPathButton = new System.Windows.Forms.Button();
+ this.discImageCreatorPathLabel = new System.Windows.Forms.Label();
+ this.subdumpPathLabel = new System.Windows.Forms.Label();
+ this.defaultOutputPathLabel = new System.Windows.Forms.Label();
+ this.DICPathTextBox = new System.Windows.Forms.TextBox();
+ this.SubDumpPathTextBox = new System.Windows.Forms.TextBox();
+ this.DefaultOutputPathTextBox = new System.Windows.Forms.TextBox();
+ this.DICPathButton = new System.Windows.Forms.Button();
+ this.preferredSpeedGroupBox = new System.Windows.Forms.GroupBox();
+ this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
+ this.DumpSpeedCDLabel = new System.Windows.Forms.Label();
+ this.DumpSpeedDVDLabel = new System.Windows.Forms.Label();
+ this.DumpSpeedBDLabel = new System.Windows.Forms.Label();
+ this.DumpSpeedCDSlider = new System.Windows.Forms.TrackBar();
+ this.DumpSpeedDVDSlider = new System.Windows.Forms.TrackBar();
+ this.DumpSpeedBDSlider = new System.Windows.Forms.TrackBar();
+ this.DumpSpeedCDTextBox = new System.Windows.Forms.TextBox();
+ this.DumpSpeedDVDTextBox = new System.Windows.Forms.TextBox();
+ this.DumpSpeedBDTextBox = new System.Windows.Forms.TextBox();
+ this.optionsGroupBox = new System.Windows.Forms.GroupBox();
+ this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
+ this.QuietModeCheckBox = new System.Windows.Forms.CheckBox();
+ this.AutoScanCheckBox = new System.Windows.Forms.CheckBox();
+ this.ParanoidModeCheckBox = new System.Windows.Forms.CheckBox();
+ this.SkipDetectionCheckBox = new System.Windows.Forms.CheckBox();
+ this.C2RereadTimesTextBox = new System.Windows.Forms.TextBox();
+ this.C2RereadLabel = new System.Windows.Forms.Label();
+ this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
+ this.AcceptButton = new System.Windows.Forms.Button();
+ this.CancelButton = new System.Windows.Forms.Button();
+ this.tableLayoutPanel1.SuspendLayout();
+ this.pathsGroupBox.SuspendLayout();
+ this.tableLayoutPanel2.SuspendLayout();
+ this.preferredSpeedGroupBox.SuspendLayout();
+ this.tableLayoutPanel3.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.DumpSpeedCDSlider)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.DumpSpeedDVDSlider)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.DumpSpeedBDSlider)).BeginInit();
+ this.optionsGroupBox.SuspendLayout();
+ this.tableLayoutPanel4.SuspendLayout();
+ this.tableLayoutPanel5.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // tableLayoutPanel1
+ //
+ this.tableLayoutPanel1.ColumnCount = 1;
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel1.Controls.Add(this.pathsGroupBox, 0, 0);
+ this.tableLayoutPanel1.Controls.Add(this.preferredSpeedGroupBox, 0, 1);
+ this.tableLayoutPanel1.Controls.Add(this.optionsGroupBox, 0, 2);
+ this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel5, 0, 3);
+ this.tableLayoutPanel1.Location = new System.Drawing.Point(12, 12);
+ this.tableLayoutPanel1.Name = "tableLayoutPanel1";
+ this.tableLayoutPanel1.RowCount = 4;
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 150F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 100F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
+ this.tableLayoutPanel1.Size = new System.Drawing.Size(475, 417);
+ this.tableLayoutPanel1.TabIndex = 0;
+ this.tableLayoutPanel1.UseWaitCursor = true;
+ //
+ // pathsGroupBox
+ //
+ this.pathsGroupBox.Controls.Add(this.tableLayoutPanel2);
+ this.pathsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.pathsGroupBox.Location = new System.Drawing.Point(3, 3);
+ this.pathsGroupBox.Name = "pathsGroupBox";
+ this.pathsGroupBox.Size = new System.Drawing.Size(469, 121);
+ this.pathsGroupBox.TabIndex = 0;
+ this.pathsGroupBox.TabStop = false;
+ this.pathsGroupBox.Text = "Paths";
+ this.pathsGroupBox.UseWaitCursor = true;
+ //
+ // tableLayoutPanel2
+ //
+ this.tableLayoutPanel2.ColumnCount = 3;
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 29.41176F));
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.82353F));
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 11.76471F));
+ this.tableLayoutPanel2.Controls.Add(this.DefaultOutputPathButton, 2, 2);
+ this.tableLayoutPanel2.Controls.Add(this.SubDumpPathButton, 2, 1);
+ this.tableLayoutPanel2.Controls.Add(this.discImageCreatorPathLabel, 0, 0);
+ this.tableLayoutPanel2.Controls.Add(this.subdumpPathLabel, 0, 1);
+ this.tableLayoutPanel2.Controls.Add(this.defaultOutputPathLabel, 0, 2);
+ this.tableLayoutPanel2.Controls.Add(this.DICPathTextBox, 1, 0);
+ this.tableLayoutPanel2.Controls.Add(this.SubDumpPathTextBox, 1, 1);
+ this.tableLayoutPanel2.Controls.Add(this.DefaultOutputPathTextBox, 1, 2);
+ this.tableLayoutPanel2.Controls.Add(this.DICPathButton, 2, 0);
+ this.tableLayoutPanel2.Location = new System.Drawing.Point(6, 15);
+ this.tableLayoutPanel2.Name = "tableLayoutPanel2";
+ this.tableLayoutPanel2.RowCount = 3;
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
+ this.tableLayoutPanel2.Size = new System.Drawing.Size(457, 100);
+ this.tableLayoutPanel2.TabIndex = 0;
+ this.tableLayoutPanel2.UseWaitCursor = true;
+ //
+ // DefaultOutputPathButton
+ //
+ this.DefaultOutputPathButton.Location = new System.Drawing.Point(405, 69);
+ this.DefaultOutputPathButton.Name = "DefaultOutputPathButton";
+ this.DefaultOutputPathButton.Size = new System.Drawing.Size(49, 23);
+ this.DefaultOutputPathButton.TabIndex = 8;
+ this.DefaultOutputPathButton.Text = "...";
+ this.DefaultOutputPathButton.UseVisualStyleBackColor = true;
+ this.DefaultOutputPathButton.UseWaitCursor = true;
+ this.DefaultOutputPathButton.Click += new System.EventHandler(this.BrowseForPathClick);
+ //
+ // SubDumpPathButton
+ //
+ this.SubDumpPathButton.Location = new System.Drawing.Point(405, 36);
+ this.SubDumpPathButton.Name = "SubDumpPathButton";
+ this.SubDumpPathButton.Size = new System.Drawing.Size(49, 23);
+ this.SubDumpPathButton.TabIndex = 7;
+ this.SubDumpPathButton.Text = "...";
+ this.SubDumpPathButton.UseVisualStyleBackColor = true;
+ this.SubDumpPathButton.UseWaitCursor = true;
+ this.SubDumpPathButton.Click += new System.EventHandler(this.BrowseForPathClick);
+ //
+ // discImageCreatorPathLabel
+ //
+ this.discImageCreatorPathLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.discImageCreatorPathLabel.AutoSize = true;
+ this.discImageCreatorPathLabel.Cursor = System.Windows.Forms.Cursors.WaitCursor;
+ this.discImageCreatorPathLabel.Location = new System.Drawing.Point(15, 10);
+ this.discImageCreatorPathLabel.Name = "discImageCreatorPathLabel";
+ this.discImageCreatorPathLabel.Size = new System.Drawing.Size(116, 13);
+ this.discImageCreatorPathLabel.TabIndex = 0;
+ this.discImageCreatorPathLabel.Text = "DiscImageCreator Path";
+ //
+ // subdumpPathLabel
+ //
+ this.subdumpPathLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.subdumpPathLabel.AutoSize = true;
+ this.subdumpPathLabel.Location = new System.Drawing.Point(56, 43);
+ this.subdumpPathLabel.Name = "subdumpPathLabel";
+ this.subdumpPathLabel.Size = new System.Drawing.Size(75, 13);
+ this.subdumpPathLabel.TabIndex = 1;
+ this.subdumpPathLabel.Text = "subdump Path";
+ this.subdumpPathLabel.UseWaitCursor = true;
+ //
+ // defaultOutputPathLabel
+ //
+ this.defaultOutputPathLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.defaultOutputPathLabel.AutoSize = true;
+ this.defaultOutputPathLabel.Location = new System.Drawing.Point(30, 76);
+ this.defaultOutputPathLabel.Name = "defaultOutputPathLabel";
+ this.defaultOutputPathLabel.Size = new System.Drawing.Size(101, 13);
+ this.defaultOutputPathLabel.TabIndex = 2;
+ this.defaultOutputPathLabel.Text = "Default Output Path";
+ this.defaultOutputPathLabel.UseWaitCursor = true;
+ //
+ // DICPathTextBox
+ //
+ this.DICPathTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.DICPathTextBox.Location = new System.Drawing.Point(138, 6);
+ this.DICPathTextBox.Name = "DICPathTextBox";
+ this.DICPathTextBox.Size = new System.Drawing.Size(259, 20);
+ this.DICPathTextBox.TabIndex = 3;
+ this.DICPathTextBox.UseWaitCursor = true;
+ //
+ // SubDumpPathTextBox
+ //
+ this.SubDumpPathTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.SubDumpPathTextBox.Location = new System.Drawing.Point(138, 39);
+ this.SubDumpPathTextBox.Name = "SubDumpPathTextBox";
+ this.SubDumpPathTextBox.Size = new System.Drawing.Size(259, 20);
+ this.SubDumpPathTextBox.TabIndex = 4;
+ this.SubDumpPathTextBox.UseWaitCursor = true;
+ //
+ // DefaultOutputPathTextBox
+ //
+ this.DefaultOutputPathTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.DefaultOutputPathTextBox.Location = new System.Drawing.Point(138, 73);
+ this.DefaultOutputPathTextBox.Name = "DefaultOutputPathTextBox";
+ this.DefaultOutputPathTextBox.Size = new System.Drawing.Size(259, 20);
+ this.DefaultOutputPathTextBox.TabIndex = 5;
+ this.DefaultOutputPathTextBox.UseWaitCursor = true;
+ //
+ // DICPathButton
+ //
+ this.DICPathButton.Location = new System.Drawing.Point(405, 3);
+ this.DICPathButton.Name = "DICPathButton";
+ this.DICPathButton.Size = new System.Drawing.Size(49, 23);
+ this.DICPathButton.TabIndex = 6;
+ this.DICPathButton.Text = "...";
+ this.DICPathButton.UseVisualStyleBackColor = true;
+ this.DICPathButton.UseWaitCursor = true;
+ this.DICPathButton.Click += new System.EventHandler(this.BrowseForPathClick);
+ //
+ // preferredSpeedGroupBox
+ //
+ this.preferredSpeedGroupBox.Controls.Add(this.tableLayoutPanel3);
+ this.preferredSpeedGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.preferredSpeedGroupBox.Location = new System.Drawing.Point(3, 130);
+ this.preferredSpeedGroupBox.Name = "preferredSpeedGroupBox";
+ this.preferredSpeedGroupBox.Size = new System.Drawing.Size(469, 144);
+ this.preferredSpeedGroupBox.TabIndex = 1;
+ this.preferredSpeedGroupBox.TabStop = false;
+ this.preferredSpeedGroupBox.Text = "Preferred Dump Speed";
+ this.preferredSpeedGroupBox.UseWaitCursor = true;
+ //
+ // tableLayoutPanel3
+ //
+ this.tableLayoutPanel3.ColumnCount = 3;
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F));
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 40F));
+ this.tableLayoutPanel3.Controls.Add(this.DumpSpeedCDLabel, 0, 0);
+ this.tableLayoutPanel3.Controls.Add(this.DumpSpeedDVDLabel, 0, 1);
+ this.tableLayoutPanel3.Controls.Add(this.DumpSpeedBDLabel, 0, 2);
+ this.tableLayoutPanel3.Controls.Add(this.DumpSpeedCDSlider, 1, 0);
+ this.tableLayoutPanel3.Controls.Add(this.DumpSpeedDVDSlider, 1, 1);
+ this.tableLayoutPanel3.Controls.Add(this.DumpSpeedBDSlider, 1, 2);
+ this.tableLayoutPanel3.Controls.Add(this.DumpSpeedCDTextBox, 2, 0);
+ this.tableLayoutPanel3.Controls.Add(this.DumpSpeedDVDTextBox, 2, 1);
+ this.tableLayoutPanel3.Controls.Add(this.DumpSpeedBDTextBox, 2, 2);
+ this.tableLayoutPanel3.Location = new System.Drawing.Point(6, 19);
+ this.tableLayoutPanel3.Name = "tableLayoutPanel3";
+ this.tableLayoutPanel3.RowCount = 3;
+ this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
+ this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
+ this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
+ this.tableLayoutPanel3.Size = new System.Drawing.Size(457, 119);
+ this.tableLayoutPanel3.TabIndex = 0;
+ this.tableLayoutPanel3.UseWaitCursor = true;
+ //
+ // DumpSpeedCDLabel
+ //
+ this.DumpSpeedCDLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.DumpSpeedCDLabel.AutoSize = true;
+ this.DumpSpeedCDLabel.Location = new System.Drawing.Point(3, 13);
+ this.DumpSpeedCDLabel.Name = "DumpSpeedCDLabel";
+ this.DumpSpeedCDLabel.Size = new System.Drawing.Size(50, 13);
+ this.DumpSpeedCDLabel.TabIndex = 0;
+ this.DumpSpeedCDLabel.Text = "CD-ROM";
+ this.DumpSpeedCDLabel.UseWaitCursor = true;
+ //
+ // DumpSpeedDVDLabel
+ //
+ this.DumpSpeedDVDLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.DumpSpeedDVDLabel.AutoSize = true;
+ this.DumpSpeedDVDLabel.Location = new System.Drawing.Point(3, 52);
+ this.DumpSpeedDVDLabel.Name = "DumpSpeedDVDLabel";
+ this.DumpSpeedDVDLabel.Size = new System.Drawing.Size(58, 13);
+ this.DumpSpeedDVDLabel.TabIndex = 1;
+ this.DumpSpeedDVDLabel.Text = "DVD-ROM";
+ this.DumpSpeedDVDLabel.UseWaitCursor = true;
+ //
+ // DumpSpeedBDLabel
+ //
+ this.DumpSpeedBDLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.DumpSpeedBDLabel.AutoSize = true;
+ this.DumpSpeedBDLabel.Location = new System.Drawing.Point(3, 92);
+ this.DumpSpeedBDLabel.Name = "DumpSpeedBDLabel";
+ this.DumpSpeedBDLabel.Size = new System.Drawing.Size(50, 13);
+ this.DumpSpeedBDLabel.TabIndex = 2;
+ this.DumpSpeedBDLabel.Text = "BD-ROM";
+ this.DumpSpeedBDLabel.UseWaitCursor = true;
+ //
+ // DumpSpeedCDSlider
+ //
+ this.DumpSpeedCDSlider.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.DumpSpeedCDSlider.Location = new System.Drawing.Point(83, 3);
+ this.DumpSpeedCDSlider.Name = "DumpSpeedCDSlider";
+ this.DumpSpeedCDSlider.Size = new System.Drawing.Size(331, 33);
+ this.DumpSpeedCDSlider.TabIndex = 3;
+ this.DumpSpeedCDSlider.UseWaitCursor = true;
+ this.DumpSpeedCDSlider.Value = 1;
+ this.DumpSpeedCDSlider.Scroll += new System.EventHandler(this.SliderChanged);
+ //
+ // DumpSpeedDVDSlider
+ //
+ this.DumpSpeedDVDSlider.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.DumpSpeedDVDSlider.Location = new System.Drawing.Point(83, 42);
+ this.DumpSpeedDVDSlider.Name = "DumpSpeedDVDSlider";
+ this.DumpSpeedDVDSlider.Size = new System.Drawing.Size(331, 33);
+ this.DumpSpeedDVDSlider.TabIndex = 4;
+ this.DumpSpeedDVDSlider.UseWaitCursor = true;
+ this.DumpSpeedDVDSlider.Value = 1;
+ this.DumpSpeedDVDSlider.Scroll += new System.EventHandler(this.SliderChanged);
+ //
+ // DumpSpeedBDSlider
+ //
+ this.DumpSpeedBDSlider.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.DumpSpeedBDSlider.Location = new System.Drawing.Point(83, 81);
+ this.DumpSpeedBDSlider.Name = "DumpSpeedBDSlider";
+ this.DumpSpeedBDSlider.Size = new System.Drawing.Size(331, 35);
+ this.DumpSpeedBDSlider.TabIndex = 5;
+ this.DumpSpeedBDSlider.UseWaitCursor = true;
+ this.DumpSpeedBDSlider.Value = 1;
+ this.DumpSpeedBDSlider.Scroll += new System.EventHandler(this.SliderChanged);
+ //
+ // DumpSpeedCDTextBox
+ //
+ this.DumpSpeedCDTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.DumpSpeedCDTextBox.Enabled = false;
+ this.DumpSpeedCDTextBox.Location = new System.Drawing.Point(420, 9);
+ this.DumpSpeedCDTextBox.Name = "DumpSpeedCDTextBox";
+ this.DumpSpeedCDTextBox.ReadOnly = true;
+ this.DumpSpeedCDTextBox.Size = new System.Drawing.Size(34, 20);
+ this.DumpSpeedCDTextBox.TabIndex = 6;
+ this.DumpSpeedCDTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
+ this.DumpSpeedCDTextBox.UseWaitCursor = true;
+ //
+ // DumpSpeedDVDTextBox
+ //
+ this.DumpSpeedDVDTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.DumpSpeedDVDTextBox.Enabled = false;
+ this.DumpSpeedDVDTextBox.Location = new System.Drawing.Point(420, 48);
+ this.DumpSpeedDVDTextBox.Name = "DumpSpeedDVDTextBox";
+ this.DumpSpeedDVDTextBox.ReadOnly = true;
+ this.DumpSpeedDVDTextBox.Size = new System.Drawing.Size(34, 20);
+ this.DumpSpeedDVDTextBox.TabIndex = 7;
+ this.DumpSpeedDVDTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
+ this.DumpSpeedDVDTextBox.UseWaitCursor = true;
+ //
+ // DumpSpeedBDTextBox
+ //
+ this.DumpSpeedBDTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.DumpSpeedBDTextBox.Enabled = false;
+ this.DumpSpeedBDTextBox.Location = new System.Drawing.Point(420, 88);
+ this.DumpSpeedBDTextBox.Name = "DumpSpeedBDTextBox";
+ this.DumpSpeedBDTextBox.ReadOnly = true;
+ this.DumpSpeedBDTextBox.Size = new System.Drawing.Size(34, 20);
+ this.DumpSpeedBDTextBox.TabIndex = 8;
+ this.DumpSpeedBDTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
+ this.DumpSpeedBDTextBox.UseWaitCursor = true;
+ //
+ // optionsGroupBox
+ //
+ this.optionsGroupBox.Controls.Add(this.tableLayoutPanel4);
+ this.optionsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.optionsGroupBox.Location = new System.Drawing.Point(3, 280);
+ this.optionsGroupBox.Name = "optionsGroupBox";
+ this.optionsGroupBox.Size = new System.Drawing.Size(469, 94);
+ this.optionsGroupBox.TabIndex = 2;
+ this.optionsGroupBox.TabStop = false;
+ this.optionsGroupBox.Text = "Options";
+ //
+ // tableLayoutPanel4
+ //
+ this.tableLayoutPanel4.ColumnCount = 4;
+ this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
+ this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
+ this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
+ this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
+ this.tableLayoutPanel4.Controls.Add(this.QuietModeCheckBox, 0, 0);
+ this.tableLayoutPanel4.Controls.Add(this.AutoScanCheckBox, 0, 1);
+ this.tableLayoutPanel4.Controls.Add(this.ParanoidModeCheckBox, 1, 0);
+ this.tableLayoutPanel4.Controls.Add(this.SkipDetectionCheckBox, 2, 1);
+ this.tableLayoutPanel4.Controls.Add(this.C2RereadTimesTextBox, 3, 0);
+ this.tableLayoutPanel4.Controls.Add(this.C2RereadLabel, 2, 0);
+ this.tableLayoutPanel4.Location = new System.Drawing.Point(6, 19);
+ this.tableLayoutPanel4.Name = "tableLayoutPanel4";
+ this.tableLayoutPanel4.RowCount = 2;
+ this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.tableLayoutPanel4.Size = new System.Drawing.Size(457, 69);
+ this.tableLayoutPanel4.TabIndex = 0;
+ //
+ // QuietModeCheckBox
+ //
+ this.QuietModeCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.QuietModeCheckBox.AutoSize = true;
+ this.QuietModeCheckBox.Location = new System.Drawing.Point(3, 8);
+ this.QuietModeCheckBox.Name = "QuietModeCheckBox";
+ this.QuietModeCheckBox.Size = new System.Drawing.Size(81, 17);
+ this.QuietModeCheckBox.TabIndex = 0;
+ this.QuietModeCheckBox.Text = "Quiet Mode";
+ this.QuietModeCheckBox.UseVisualStyleBackColor = true;
+ //
+ // AutoScanCheckBox
+ //
+ this.AutoScanCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.AutoScanCheckBox.AutoSize = true;
+ this.tableLayoutPanel4.SetColumnSpan(this.AutoScanCheckBox, 2);
+ this.AutoScanCheckBox.Location = new System.Drawing.Point(3, 43);
+ this.AutoScanCheckBox.Name = "AutoScanCheckBox";
+ this.AutoScanCheckBox.Size = new System.Drawing.Size(182, 17);
+ this.AutoScanCheckBox.TabIndex = 1;
+ this.AutoScanCheckBox.Text = "Automatically Scan for Protection";
+ this.AutoScanCheckBox.UseVisualStyleBackColor = true;
+ //
+ // ParanoidModeCheckBox
+ //
+ this.ParanoidModeCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.ParanoidModeCheckBox.AutoSize = true;
+ this.ParanoidModeCheckBox.Location = new System.Drawing.Point(117, 8);
+ this.ParanoidModeCheckBox.Name = "ParanoidModeCheckBox";
+ this.ParanoidModeCheckBox.Size = new System.Drawing.Size(98, 17);
+ this.ParanoidModeCheckBox.TabIndex = 2;
+ this.ParanoidModeCheckBox.Text = "Paranoid Mode";
+ this.ParanoidModeCheckBox.UseVisualStyleBackColor = true;
+ //
+ // SkipDetectionCheckBox
+ //
+ this.SkipDetectionCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.SkipDetectionCheckBox.AutoSize = true;
+ this.tableLayoutPanel4.SetColumnSpan(this.SkipDetectionCheckBox, 2);
+ this.SkipDetectionCheckBox.Location = new System.Drawing.Point(231, 43);
+ this.SkipDetectionCheckBox.Name = "SkipDetectionCheckBox";
+ this.SkipDetectionCheckBox.Size = new System.Drawing.Size(155, 17);
+ this.SkipDetectionCheckBox.TabIndex = 3;
+ this.SkipDetectionCheckBox.Text = "Skip Media Type Detection";
+ this.SkipDetectionCheckBox.UseVisualStyleBackColor = true;
+ //
+ // C2RereadTimesTextBox
+ //
+ this.C2RereadTimesTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.C2RereadTimesTextBox.Location = new System.Drawing.Point(349, 7);
+ this.C2RereadTimesTextBox.Name = "C2RereadTimesTextBox";
+ this.C2RereadTimesTextBox.Size = new System.Drawing.Size(100, 20);
+ this.C2RereadTimesTextBox.TabIndex = 4;
+ //
+ // C2RereadLabel
+ //
+ this.C2RereadLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.C2RereadLabel.AutoSize = true;
+ this.C2RereadLabel.Location = new System.Drawing.Point(250, 10);
+ this.C2RereadLabel.Name = "C2RereadLabel";
+ this.C2RereadLabel.Size = new System.Drawing.Size(89, 13);
+ this.C2RereadLabel.TabIndex = 5;
+ this.C2RereadLabel.Text = "C2 Reread Times";
+ //
+ // tableLayoutPanel5
+ //
+ this.tableLayoutPanel5.ColumnCount = 2;
+ this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.tableLayoutPanel5.Controls.Add(this.AcceptButton, 0, 0);
+ this.tableLayoutPanel5.Controls.Add(this.CancelButton, 1, 0);
+ this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel5.Location = new System.Drawing.Point(3, 380);
+ this.tableLayoutPanel5.Name = "tableLayoutPanel5";
+ this.tableLayoutPanel5.RowCount = 1;
+ this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
+ this.tableLayoutPanel5.Size = new System.Drawing.Size(469, 34);
+ this.tableLayoutPanel5.TabIndex = 3;
+ //
+ // AcceptButton
+ //
+ this.AcceptButton.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.AcceptButton.Location = new System.Drawing.Point(79, 5);
+ this.AcceptButton.Name = "AcceptButton";
+ this.AcceptButton.Size = new System.Drawing.Size(75, 23);
+ this.AcceptButton.TabIndex = 0;
+ this.AcceptButton.Text = "Accept";
+ this.AcceptButton.UseVisualStyleBackColor = true;
+ this.AcceptButton.Click += new System.EventHandler(this.OnAcceptClick);
+ //
+ // CancelButton
+ //
+ this.CancelButton.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.CancelButton.Location = new System.Drawing.Point(314, 5);
+ this.CancelButton.Name = "CancelButton";
+ this.CancelButton.Size = new System.Drawing.Size(75, 23);
+ this.CancelButton.TabIndex = 1;
+ this.CancelButton.Text = "Cancel";
+ this.CancelButton.UseVisualStyleBackColor = true;
+ this.CancelButton.Click += new System.EventHandler(this.OnCancelClick);
+ //
+ // OptionsWindow
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(499, 441);
+ this.Controls.Add(this.tableLayoutPanel1);
+ this.Name = "OptionsWindow";
+ this.ShowIcon = false;
+ this.Text = "Options";
+ this.UseWaitCursor = true;
+ this.tableLayoutPanel1.ResumeLayout(false);
+ this.pathsGroupBox.ResumeLayout(false);
+ this.tableLayoutPanel2.ResumeLayout(false);
+ this.tableLayoutPanel2.PerformLayout();
+ this.preferredSpeedGroupBox.ResumeLayout(false);
+ this.tableLayoutPanel3.ResumeLayout(false);
+ this.tableLayoutPanel3.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.DumpSpeedCDSlider)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.DumpSpeedDVDSlider)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.DumpSpeedBDSlider)).EndInit();
+ this.optionsGroupBox.ResumeLayout(false);
+ this.tableLayoutPanel4.ResumeLayout(false);
+ this.tableLayoutPanel4.PerformLayout();
+ this.tableLayoutPanel5.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
+ private System.Windows.Forms.GroupBox pathsGroupBox;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
+ private System.Windows.Forms.Label discImageCreatorPathLabel;
+ private System.Windows.Forms.Label subdumpPathLabel;
+ private System.Windows.Forms.Label defaultOutputPathLabel;
+ private System.Windows.Forms.TextBox DICPathTextBox;
+ private System.Windows.Forms.TextBox SubDumpPathTextBox;
+ private System.Windows.Forms.TextBox DefaultOutputPathTextBox;
+ private System.Windows.Forms.Button DICPathButton;
+ private System.Windows.Forms.Button DefaultOutputPathButton;
+ private System.Windows.Forms.Button SubDumpPathButton;
+ private System.Windows.Forms.GroupBox preferredSpeedGroupBox;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
+ private System.Windows.Forms.Label DumpSpeedCDLabel;
+ private System.Windows.Forms.Label DumpSpeedDVDLabel;
+ private System.Windows.Forms.Label DumpSpeedBDLabel;
+ private System.Windows.Forms.TrackBar DumpSpeedCDSlider;
+ private System.Windows.Forms.TrackBar DumpSpeedDVDSlider;
+ private System.Windows.Forms.TrackBar DumpSpeedBDSlider;
+ private System.Windows.Forms.TextBox DumpSpeedCDTextBox;
+ private System.Windows.Forms.TextBox DumpSpeedDVDTextBox;
+ private System.Windows.Forms.TextBox DumpSpeedBDTextBox;
+ private System.Windows.Forms.GroupBox optionsGroupBox;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
+ private System.Windows.Forms.CheckBox QuietModeCheckBox;
+ private System.Windows.Forms.CheckBox AutoScanCheckBox;
+ private System.Windows.Forms.CheckBox ParanoidModeCheckBox;
+ private System.Windows.Forms.CheckBox SkipDetectionCheckBox;
+ private System.Windows.Forms.TextBox C2RereadTimesTextBox;
+ private System.Windows.Forms.Label C2RereadLabel;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5;
+ private System.Windows.Forms.Button AcceptButton;
+ private System.Windows.Forms.Button CancelButton;
+ }
+}
\ No newline at end of file
diff --git a/DICUI.Forms/Windows/OptionsWindow.cs b/DICUI.Forms/Windows/OptionsWindow.cs
new file mode 100644
index 00000000..5043d417
--- /dev/null
+++ b/DICUI.Forms/Windows/OptionsWindow.cs
@@ -0,0 +1,179 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Forms;
+
+namespace DICUI.Forms.Windows
+{
+ ///
+ /// Interaction logic for OptionsWindow
+ ///
+ public partial class OptionsWindow : Form
+ {
+ private readonly MainWindow _mainWindow;
+ private readonly Options _options;
+
+ public OptionsWindow(MainWindow mainWindow, Options options)
+ {
+ InitializeComponent();
+ _mainWindow = mainWindow;
+ _options = options;
+
+ // Create data sets
+ DumpSpeedCDSlider.Minimum = (int)Constants.SpeedsForCDAsCollection.First();
+ DumpSpeedCDSlider.Maximum = (int)Constants.SpeedsForCDAsCollection.Last();
+ DumpSpeedDVDSlider.Minimum = (int)Constants.SpeedsForDVDAsCollection.First();
+ DumpSpeedDVDSlider.Maximum = (int)Constants.SpeedsForDVDAsCollection.Last();
+ DumpSpeedBDSlider.Minimum = (int)Constants.SpeedsForBDAsCollection.First();
+ DumpSpeedBDSlider.Maximum = (int)Constants.SpeedsForBDAsCollection.Last();
+
+ // Select the current values
+ DumpSpeedCDSlider.Value = _options.preferredDumpSpeedCD;
+ DumpSpeedDVDSlider.Value = _options.preferredDumpSpeedDVD;
+ DumpSpeedBDSlider.Value = _options.preferredDumpSpeedBD;
+
+ // Create textbox outputs
+ DumpSpeedCDTextBox.Text = DumpSpeedCDSlider.Value.ToString();
+ DumpSpeedDVDTextBox.Text = DumpSpeedDVDSlider.Value.ToString();
+ DumpSpeedBDTextBox.Text = DumpSpeedBDSlider.Value.ToString();
+
+ // Set options
+ QuietModeCheckBox.Checked = _options.QuietMode;
+ ParanoidModeCheckBox.Checked = _options.ParanoidMode;
+ C2RereadTimesTextBox.Text = _options.RereadAmountForC2.ToString();
+ AutoScanCheckBox.Checked = _options.ScanForProtection;
+ SkipDetectionCheckBox.Checked = _options.SkipMediaTypeDetection;
+ }
+
+ private OpenFileDialog CreateOpenFileDialog()
+ {
+ OpenFileDialog dialog = new OpenFileDialog();
+
+ dialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
+ dialog.Filter = "Executables (*.exe)|*.exe";
+ dialog.FilterIndex = 0;
+ dialog.RestoreDirectory = true;
+
+ return dialog;
+ }
+
+ private FolderBrowserDialog CreateFolderBrowserDialog()
+ {
+ FolderBrowserDialog dialog = new FolderBrowserDialog();
+ return dialog;
+ }
+
+ private string[] PathSettings()
+ {
+ string[] pathSettings = { "DefaultOutputPath", "DICPath", "SubDumpPath" };
+ return pathSettings;
+ }
+
+ private TextBox TextBoxForPathSetting(string name)
+ {
+ switch (name)
+ {
+ case "DICPath":
+ return DICPathTextBox;
+ case "SubDumpPath":
+ return SubDumpPathTextBox;
+ case "DefaultOutputPath":
+ return DefaultOutputPathTextBox;
+ default:
+ return null;
+ }
+ }
+
+ private void BrowseForPathClick(object sender, EventArgs e)
+ {
+ Button button = sender as Button;
+ // strips button prefix to obtain the setting name
+ string pathSettingName = button.Name.Substring(0, button.Name.IndexOf("Button"));
+
+ // TODO: hack for now, then we'll see
+ bool shouldBrowseForPath = pathSettingName == "DefaultOutputPath";
+
+ CommonDialog dialog = shouldBrowseForPath ? (CommonDialog)CreateFolderBrowserDialog() : CreateOpenFileDialog();
+ using (dialog)
+ {
+ DialogResult result = dialog.ShowDialog();
+
+ if (result == System.Windows.Forms.DialogResult.OK)
+ {
+ string path;
+ bool exists;
+
+ if (shouldBrowseForPath)
+ {
+ path = (dialog as FolderBrowserDialog).SelectedPath;
+ exists = Directory.Exists(path);
+ }
+ else
+ {
+ path = (dialog as OpenFileDialog).FileName;
+ exists = File.Exists(path);
+ }
+
+ if (exists)
+ TextBoxForPathSetting(pathSettingName).Text = path;
+ else
+ {
+ System.Windows.MessageBox.Show(
+ "Specified path doesn't exists!",
+ "Error",
+ MessageBoxButton.OK,
+ MessageBoxImage.Error
+ );
+ }
+ }
+ }
+ }
+
+ public void RefreshSettings()
+ {
+ Array.ForEach(PathSettings(), setting => TextBoxForPathSetting(setting).Text = _options.Get(setting));
+
+ DumpSpeedCDSlider.Value = _options.preferredDumpSpeedCD;
+ DumpSpeedDVDSlider.Value = _options.preferredDumpSpeedDVD;
+ DumpSpeedBDSlider.Value = _options.preferredDumpSpeedBD;
+ }
+
+ #region Event Handlers
+
+ private void SliderChanged(object sender, EventArgs e)
+ {
+ DumpSpeedCDTextBox.Text = DumpSpeedCDSlider.Value.ToString();
+ DumpSpeedDVDTextBox.Text = DumpSpeedDVDSlider.Value.ToString();
+ DumpSpeedBDTextBox.Text = DumpSpeedBDSlider.Value.ToString();
+ }
+
+ private void OnAcceptClick(object sender, EventArgs e)
+ {
+ Array.ForEach(PathSettings(), setting => _options.Set(setting, TextBoxForPathSetting(setting).Text));
+
+ _options.preferredDumpSpeedCD = Convert.ToInt32(DumpSpeedCDSlider.Value);
+ _options.preferredDumpSpeedDVD = Convert.ToInt32(DumpSpeedDVDSlider.Value);
+ _options.preferredDumpSpeedBD = Convert.ToInt32(DumpSpeedBDSlider.Value);
+
+ _options.QuietMode = QuietModeCheckBox.Checked;
+ _options.ParanoidMode = ParanoidModeCheckBox.Checked;
+ _options.RereadAmountForC2 = Convert.ToInt32(C2RereadTimesTextBox.Text);
+ _options.ScanForProtection = AutoScanCheckBox.Checked;
+ _options.SkipMediaTypeDetection = SkipDetectionCheckBox.Checked;
+
+ _options.Save();
+ Hide();
+
+ _mainWindow.OnOptionsUpdated();
+ }
+
+ private void OnCancelClick(object sender, EventArgs e)
+ {
+ // just hide the window and don't care
+ Hide();
+ }
+
+ #endregion
+ }
+}
diff --git a/DICUI.Forms/Windows/OptionsWindow.resx b/DICUI.Forms/Windows/OptionsWindow.resx
new file mode 100644
index 00000000..61bc649b
--- /dev/null
+++ b/DICUI.Forms/Windows/OptionsWindow.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
\ No newline at end of file
diff --git a/DICUI.Library/DICUI.Library.csproj b/DICUI.Library/DICUI.Library.csproj
new file mode 100644
index 00000000..148c0cd0
--- /dev/null
+++ b/DICUI.Library/DICUI.Library.csproj
@@ -0,0 +1,101 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {51AB0928-13F9-44BF-A407-B6957A43A056}
+ Library
+ Properties
+ DICUI.Library
+ DICUI.Library
+ v4.6.1
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\BurnOutSharp.1.3.7.1\lib\net461\BurnOutSharp.dll
+
+
+ ..\packages\LessIO.0.5.0\lib\net40\LessIO.dll
+
+
+ ..\packages\libmspack4n.0.8.0\lib\net40\libmspackn.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\packages\UnshieldSharp.1.4.2.2\lib\net461\UnshieldSharp.dll
+
+
+ ..\packages\zlib.net.1.0.4.0\lib\zlib.net.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
+ {2735412F-7F64-5B0F-8F00-5D77AFBE261E}
+ 1
+ 0
+ 0
+ tlbimp
+ False
+ True
+
+
+ {2C941FD0-975B-59BE-A960-9A2A262853A5}
+ 1
+ 0
+ 0
+ tlbimp
+ False
+ True
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DICUI/Data/Constants.cs b/DICUI.Library/Data/Constants.cs
similarity index 94%
rename from DICUI/Data/Constants.cs
rename to DICUI.Library/Data/Constants.cs
index ef0afbfb..f0b36f78 100644
--- a/DICUI/Data/Constants.cs
+++ b/DICUI.Library/Data/Constants.cs
@@ -1,17 +1,5 @@
namespace DICUI.Data
{
- ///
- /// Variables for UI elements
- ///
- public static class UIElements
- {
- public const string DiscNotDetected = "Disc Not Detected";
- public const string StartDumping = "Start Dumping";
- public const string StopDumping = "Stop Dumping";
-
- public const int LogWindowMarginFromMainWindow = 10;
- }
-
///
/// Top-level commands for DiscImageCreator
///
@@ -125,5 +113,6 @@
public const string RequiredIfExistsValue = "(REQUIRED, IF EXISTS)";
public const string OptionalValue = "(OPTIONAL)";
public const string YesNoValue = "Yes/No";
+ public const string DiscNotDetected = "Disc Not Detected";
}
}
diff --git a/DICUI/Data/Enumerations.cs b/DICUI.Library/Data/Enumerations.cs
similarity index 100%
rename from DICUI/Data/Enumerations.cs
rename to DICUI.Library/Data/Enumerations.cs
diff --git a/DICUI.Library/Properties/AssemblyInfo.cs b/DICUI.Library/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..331f1859
--- /dev/null
+++ b/DICUI.Library/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("DICUI.Library")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DICUI.Library")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("51ab0928-13f9-44bf-a407-b6957a43a056")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/DICUI/Utilities/Converters.cs b/DICUI.Library/Utilities/Converters.cs
similarity index 96%
rename from DICUI/Utilities/Converters.cs
rename to DICUI.Library/Utilities/Converters.cs
index f404ca52..b7c63d95 100644
--- a/DICUI/Utilities/Converters.cs
+++ b/DICUI.Library/Utilities/Converters.cs
@@ -1,36 +1,8 @@
-using System;
-using System.Globalization;
-using System.Windows.Data;
-using IMAPI2;
+using IMAPI2;
using DICUI.Data;
namespace DICUI.Utilities
{
- ///
- /// Used to provide a converter to XAML files to render comboboxes with enum values
- ///
- public class EnumDescriptionConverter : IValueConverter
- {
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- if (value is DICCommand)
- return ((DICCommand)value).Name();
- else if (value is DICFlag)
- return ((DICFlag)value).Name();
- else if (value is MediaType?)
- return ((MediaType?)value).Name();
- else if (value is KnownSystem?)
- return ((KnownSystem?)value).Name();
- else
- return "";
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- return string.Empty;
- }
- }
-
public static class Converters
{
///
diff --git a/DICUI/Utilities/DumpEnvironment.cs b/DICUI.Library/Utilities/DumpEnvironment.cs
similarity index 97%
rename from DICUI/Utilities/DumpEnvironment.cs
rename to DICUI.Library/Utilities/DumpEnvironment.cs
index 1f206017..3ef6906c 100644
--- a/DICUI/Utilities/DumpEnvironment.cs
+++ b/DICUI.Library/Utilities/DumpEnvironment.cs
@@ -6,9 +6,7 @@ using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
-using System.Windows;
using DICUI.Data;
-using DICUI.UI;
namespace DICUI.Utilities
{
@@ -70,8 +68,6 @@ namespace DICUI.Utilities
///
public void CancelDumping()
{
- ViewModels.LoggerViewModel.VerboseLogLn("Canceling dumping process...");
-
try
{
if (dicProcess != null && !dicProcess.HasExited)
@@ -86,8 +82,6 @@ namespace DICUI.Utilities
///
public async void EjectDisc()
{
- ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {Drive.Letter}");
-
// Validate that the required program exists
if (!File.Exists(DICPath))
return;
@@ -164,10 +158,7 @@ namespace DICUI.Utilities
// If we get the firmware message
if (output.Contains("[ERROR] This drive isn't latest firmware. Please update."))
- {
- MessageBox.Show($"DiscImageCreator has reported that drive {Drive.Letter} is not updated to the most recent firmware. Please update the firmware for your drive and try again.", "Outdated Firmware", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
- }
// Otherwise, we know the firmware's good
return true;
@@ -237,12 +228,12 @@ namespace DICUI.Utilities
#endregion
- #region Internal for Testing Purposes
+ #region Public for Testing Purposes
///
/// Fix output paths to strip out any invalid characters
///
- internal void FixOutputPaths()
+ public void FixOutputPaths()
{
try
{
@@ -285,11 +276,73 @@ namespace DICUI.Utilities
/// Checks if the parameters are valid
///
/// True if the configuration is valid, false otherwise
- internal bool ParametersValid()
+ public bool ParametersValid()
{
return DICParameters.IsValid() && !(IsFloppy ^ Type == MediaType.FloppyDisk);
}
+ ///
+ /// Ensures that all required output files have been created
+ ///
+ ///
+ public bool FoundAllFiles()
+ {
+ // First, sanitized the output filename to strip off any potential extension
+ string outputFilename = Path.GetFileNameWithoutExtension(OutputFilename);
+
+ // Now ensure that all required files exist
+ string combinedBase = Path.Combine(OutputDirectory, outputFilename);
+ switch (Type)
+ {
+ case MediaType.CDROM:
+ case MediaType.GDROM: // TODO: Verify GD-ROM outputs this
+ return File.Exists(combinedBase + ".c2")
+ && File.Exists(combinedBase + ".ccd")
+ && File.Exists(combinedBase + ".cue")
+ && File.Exists(combinedBase + ".dat")
+ && File.Exists(combinedBase + ".img")
+ && File.Exists(combinedBase + ".img_EdcEcc.txt")
+ && File.Exists(combinedBase + ".scm")
+ && File.Exists(combinedBase + ".sub")
+ && File.Exists(combinedBase + "_c2Error.txt")
+ && File.Exists(combinedBase + "_cmd.txt")
+ && File.Exists(combinedBase + "_disc.txt")
+ && File.Exists(combinedBase + "_drive.txt")
+ && File.Exists(combinedBase + "_img.cue")
+ && File.Exists(combinedBase + "_mainError.txt")
+ && File.Exists(combinedBase + "_mainInfo.txt")
+ && File.Exists(combinedBase + "_subError.txt")
+ && File.Exists(combinedBase + "_subInfo.txt")
+ // && File.Exists(combinedBase + "_subIntention.txt")
+ && (File.Exists(combinedBase + "_subReadable.txt") || File.Exists(combinedBase + "_sub.txt"))
+ && File.Exists(combinedBase + "_volDesc.txt");
+ case MediaType.DVD:
+ case MediaType.HDDVD:
+ case MediaType.BluRay:
+ case MediaType.NintendoGameCube:
+ case MediaType.NintendoWiiOpticalDisc:
+ return File.Exists(combinedBase + ".dat")
+ && File.Exists(combinedBase + "_cmd.txt")
+ && File.Exists(combinedBase + "_disc.txt")
+ && File.Exists(combinedBase + "_drive.txt")
+ && File.Exists(combinedBase + "_mainError.txt")
+ && File.Exists(combinedBase + "_mainInfo.txt")
+ && File.Exists(combinedBase + "_volDesc.txt");
+ case MediaType.FloppyDisk:
+ return File.Exists(combinedBase + ".dat")
+ && File.Exists(combinedBase + "_cmd.txt")
+ && File.Exists(combinedBase + "_disc.txt");
+ case MediaType.UMD:
+ return File.Exists(combinedBase + "_disc.txt")
+ || File.Exists(combinedBase + "_mainError.txt")
+ || File.Exists(combinedBase + "_mainInfo.txt")
+ || File.Exists(combinedBase + "_volDesc.txt");
+ default:
+ // Non-dumping commands will usually produce no output, so this is irrelevant
+ return true;
+ }
+ }
+
#endregion
#region Private Helpers
@@ -319,8 +372,6 @@ namespace DICUI.Utilities
///
private void ExecuteDiskImageCreator()
{
- ViewModels.LoggerViewModel.VerboseLogLn("Launching DiscImageCreator process.");
-
dicProcess = new Process()
{
StartInfo = new ProcessStartInfo()
@@ -764,68 +815,6 @@ namespace DICUI.Utilities
}
}
- ///
- /// Ensures that all required output files have been created
- ///
- ///
- private bool FoundAllFiles()
- {
- // First, sanitized the output filename to strip off any potential extension
- string outputFilename = Path.GetFileNameWithoutExtension(OutputFilename);
-
- // Now ensure that all required files exist
- string combinedBase = Path.Combine(OutputDirectory, outputFilename);
- switch (Type)
- {
- case MediaType.CDROM:
- case MediaType.GDROM: // TODO: Verify GD-ROM outputs this
- return File.Exists(combinedBase + ".c2")
- && File.Exists(combinedBase + ".ccd")
- && File.Exists(combinedBase + ".cue")
- && File.Exists(combinedBase + ".dat")
- && File.Exists(combinedBase + ".img")
- && File.Exists(combinedBase + ".img_EdcEcc.txt")
- && File.Exists(combinedBase + ".scm")
- && File.Exists(combinedBase + ".sub")
- && File.Exists(combinedBase + "_c2Error.txt")
- && File.Exists(combinedBase + "_cmd.txt")
- && File.Exists(combinedBase + "_disc.txt")
- && File.Exists(combinedBase + "_drive.txt")
- && File.Exists(combinedBase + "_img.cue")
- && File.Exists(combinedBase + "_mainError.txt")
- && File.Exists(combinedBase + "_mainInfo.txt")
- && File.Exists(combinedBase + "_subError.txt")
- && File.Exists(combinedBase + "_subInfo.txt")
- // && File.Exists(combinedBase + "_subIntention.txt")
- && (File.Exists(combinedBase + "_subReadable.txt") || File.Exists(combinedBase + "_sub.txt"))
- && File.Exists(combinedBase + "_volDesc.txt");
- case MediaType.DVD:
- case MediaType.HDDVD:
- case MediaType.BluRay:
- case MediaType.NintendoGameCube:
- case MediaType.NintendoWiiOpticalDisc:
- return File.Exists(combinedBase + ".dat")
- && File.Exists(combinedBase + "_cmd.txt")
- && File.Exists(combinedBase + "_disc.txt")
- && File.Exists(combinedBase + "_drive.txt")
- && File.Exists(combinedBase + "_mainError.txt")
- && File.Exists(combinedBase + "_mainInfo.txt")
- && File.Exists(combinedBase + "_volDesc.txt");
- case MediaType.FloppyDisk:
- return File.Exists(combinedBase + ".dat")
- && File.Exists(combinedBase + "_cmd.txt")
- && File.Exists(combinedBase + "_disc.txt");
- case MediaType.UMD:
- return File.Exists(combinedBase + "_disc.txt")
- || File.Exists(combinedBase + "_mainError.txt")
- || File.Exists(combinedBase + "_mainInfo.txt")
- || File.Exists(combinedBase + "_volDesc.txt");
- default:
- // Non-dumping commands will usually produce no output, so this is irrelevant
- return true;
- }
- }
-
///
/// Get the existance of an anti-modchip string from the input file, if possible
///
@@ -1601,26 +1590,6 @@ namespace DICUI.Utilities
if (!File.Exists(DICPath))
return Result.Failure("Error! Could not find DiscImageCreator!");
- // Validate that the user explicitly wants an inactive drive to be considered for dumping
- if (!Drive.MarkedActive)
- {
- MessageBoxResult result = MessageBox.Show("The currently selected drive does not appear to contain a disc! Are you sure you want to continue?", "Missing Disc", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
- if (result == MessageBoxResult.No || result == MessageBoxResult.Cancel || result == MessageBoxResult.None)
- {
- return Result.Failure("Dumping aborted!");
- }
- }
-
- // If a complete dump already exists
- if (FoundAllFiles())
- {
- MessageBoxResult result = MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
- if (result == MessageBoxResult.No || result == MessageBoxResult.Cancel || result == MessageBoxResult.None)
- {
- return Result.Failure("Dumping aborted!");
- }
- }
-
return Result.Success();
}
diff --git a/DICUI/Utilities/Extensions.cs b/DICUI.Library/Utilities/Extensions.cs
similarity index 100%
rename from DICUI/Utilities/Extensions.cs
rename to DICUI.Library/Utilities/Extensions.cs
diff --git a/DICUI/Utilities/Parameters.cs b/DICUI.Library/Utilities/Parameters.cs
similarity index 100%
rename from DICUI/Utilities/Parameters.cs
rename to DICUI.Library/Utilities/Parameters.cs
diff --git a/DICUI/Utilities/Result.cs b/DICUI.Library/Utilities/Result.cs
similarity index 100%
rename from DICUI/Utilities/Result.cs
rename to DICUI.Library/Utilities/Result.cs
diff --git a/DICUI/Utilities/Validators.cs b/DICUI.Library/Utilities/Validators.cs
similarity index 99%
rename from DICUI/Utilities/Validators.cs
rename to DICUI.Library/Utilities/Validators.cs
index e79d92b7..6586dd06 100644
--- a/DICUI/Utilities/Validators.cs
+++ b/DICUI.Library/Utilities/Validators.cs
@@ -431,7 +431,7 @@ namespace DICUI.Utilities
// Get the optical disc drives
List discDrives = DriveInfo.GetDrives()
.Where(d => d.DriveType == DriveType.CDRom)
- .Select(d => Drive.Optical(d.Name[0], (d.IsReady ? d.VolumeLabel : UIElements.DiscNotDetected), d.IsReady))
+ .Select(d => Drive.Optical(d.Name[0], (d.IsReady ? d.VolumeLabel : Template.DiscNotDetected), d.IsReady))
.ToList();
// Add the two lists together and order
diff --git a/DICUI/mspack.dll b/DICUI.Library/mspack.dll
similarity index 100%
rename from DICUI/mspack.dll
rename to DICUI.Library/mspack.dll
diff --git a/DICUI/packages.config b/DICUI.Library/packages.config
similarity index 100%
rename from DICUI/packages.config
rename to DICUI.Library/packages.config
diff --git a/DICUI.Test/DICUI.Test.csproj b/DICUI.Test/DICUI.Test.csproj
index db2befea..6be8f167 100644
--- a/DICUI.Test/DICUI.Test.csproj
+++ b/DICUI.Test/DICUI.Test.csproj
@@ -78,14 +78,18 @@
+
+
+
+
+ {51ab0928-13f9-44bf-a407-b6957a43a056}
+ DICUI.Library
+
{7b1b75eb-8940-466f-bd51-76471a57f9be}
DICUI
-
-
-
diff --git a/DICUI.Test/UI/AllowedSpeedsTest.cs b/DICUI.Test/UI/AllowedSpeedsTest.cs
index 6396b1af..386ae01c 100644
--- a/DICUI.Test/UI/AllowedSpeedsTest.cs
+++ b/DICUI.Test/UI/AllowedSpeedsTest.cs
@@ -1,6 +1,5 @@
using System.Linq;
using DICUI.Data;
-using DICUI.UI;
using Xunit;
namespace DICUI.Test.Data
@@ -15,7 +14,7 @@ namespace DICUI.Test.Data
[InlineData(null, 72)] // TODO: Update when fully determined
public void GetAllowedDriveSpeedForMediaTypeTest(MediaType? mediaType, int maxExpected)
{
- var actual = AllowedSpeeds.GetForMediaType(mediaType);
+ var actual = Constants.GetSpeedsForMediaType(mediaType);
Assert.Equal(maxExpected, actual.Last());
}
}
diff --git a/DICUI.sln b/DICUI.sln
index fcb2872d..8350a403 100644
--- a/DICUI.sln
+++ b/DICUI.sln
@@ -7,6 +7,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI", "DICUI\DICUI.csproj
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Test", "DICUI.Test\DICUI.Test.csproj", "{7CC064D2-38AB-4A05-8519-28660DE4562A}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Library", "DICUI.Library\DICUI.Library.csproj", "{51AB0928-13F9-44BF-A407-B6957A43A056}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Forms", "DICUI.Forms\DICUI.Forms.csproj", "{A6719A99-BF0E-4637-9A8E-CB38B1E16971}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +25,14 @@ Global
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {51AB0928-13F9-44BF-A407-B6957A43A056}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {51AB0928-13F9-44BF-A407-B6957A43A056}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {51AB0928-13F9-44BF-A407-B6957A43A056}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {51AB0928-13F9-44BF-A407-B6957A43A056}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A6719A99-BF0E-4637-9A8E-CB38B1E16971}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A6719A99-BF0E-4637-9A8E-CB38B1E16971}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A6719A99-BF0E-4637-9A8E-CB38B1E16971}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A6719A99-BF0E-4637-9A8E-CB38B1E16971}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/DICUI/App.xaml b/DICUI/App.xaml
index bcd42346..b9f57038 100644
--- a/DICUI/App.xaml
+++ b/DICUI/App.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DICUI"
- StartupUri="MainWindow.xaml">
+ StartupUri="Windows\MainWindow.xaml">
diff --git a/DICUI/App.xaml.cs b/DICUI/App.xaml.cs
index 138640a0..4f140534 100644
--- a/DICUI/App.xaml.cs
+++ b/DICUI/App.xaml.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Data;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows;
+using System.Windows;
namespace DICUI
{
diff --git a/DICUI/Constants.cs b/DICUI/Constants.cs
new file mode 100644
index 00000000..678aef96
--- /dev/null
+++ b/DICUI/Constants.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Media;
+using DICUI.Data;
+
+namespace DICUI
+{
+ ///
+ /// Variables for UI elements
+ ///
+ public static class Constants
+ {
+ public const string StartDumping = "Start Dumping";
+ public const string StopDumping = "Stop Dumping";
+
+ public const int LogWindowMarginFromMainWindow = 10;
+
+ // Private lists of known drive speed ranges
+ private static IReadOnlyList cd { get; } = new List { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 };
+ private static IReadOnlyList dvd { get; } = cd.Where(s => s <= 24).ToList();
+ private static IReadOnlyList bd { get; } = cd.Where(s => s <= 16).ToList();
+ private static IReadOnlyList unknown { get; } = cd; // TODO: All or {1}? Maybe null?
+
+ ///
+ /// Get list of all drive speeds for a given MediaType
+ ///
+ /// MediaType? that represents the current item
+ /// Read-only list of drive speeds
+ public static IReadOnlyList GetSpeedsForMediaType(MediaType? type)
+ {
+ switch (type)
+ {
+ case MediaType.CDROM:
+ case MediaType.GDROM:
+ return cd;
+ case MediaType.DVD:
+ case MediaType.HDDVD:
+ case MediaType.NintendoGameCube:
+ case MediaType.NintendoWiiOpticalDisc:
+ return dvd;
+ case MediaType.BluRay:
+ return bd;
+ default:
+ return unknown;
+ }
+ }
+
+ // Create collections for UI based on known drive speeds
+ public static DoubleCollection SpeedsForCDAsCollection { get; } = GetDoubleCollectionFromIntList(cd);
+ public static DoubleCollection SpeedsForDVDAsCollection { get; } = GetDoubleCollectionFromIntList(dvd);
+ public static DoubleCollection SpeedsForBDAsCollection { get; } = GetDoubleCollectionFromIntList(bd);
+ private static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList list)
+ => new DoubleCollection(list.Select(i => Convert.ToDouble(i)).ToList());
+ }
+}
diff --git a/DICUI/DICUI.csproj b/DICUI/DICUI.csproj
index 2c79be4b..e1708fa4 100644
--- a/DICUI/DICUI.csproj
+++ b/DICUI/DICUI.csproj
@@ -67,68 +67,42 @@
-
- ..\packages\BurnOutSharp.1.3.7.1\lib\net461\BurnOutSharp.dll
-
-
- ..\packages\LessIO.0.5.0\lib\net40\LessIO.dll
-
-
- ..\packages\libmspack4n.0.8.0\lib\net40\libmspackn.dll
-
-
-
-
-
-
4.0
-
- ..\packages\UnshieldSharp.1.4.2.2\lib\net461\UnshieldSharp.dll
-
-
- ..\packages\zlib.net.1.0.4.0\lib\zlib.net.dll
-
MSBuild:Compile
Designer
-
+
+
+
+
LogWindow.xaml
-
-
-
-
-
-
-
-
-
-
-
-
+
OptionsWindow.xaml
-
+
+
+
Designer
MSBuild:Compile
-
+
MSBuild:Compile
Designer
@@ -136,12 +110,11 @@
App.xaml
Code
-
-
+
MainWindow.xaml
Code
-
+
Designer
MSBuild:Compile
@@ -153,7 +126,6 @@
-
@@ -171,29 +143,10 @@
-
- {2735412F-7F64-5B0F-8F00-5D77AFBE261E}
- 1
- 0
- 0
- tlbimp
- False
- True
-
-
- {2C941FD0-975B-59BE-A960-9A2A262853A5}
- 1
- 0
- 0
- tlbimp
- False
- True
-
-
-
-
- Always
-
+
+ {51ab0928-13f9-44bf-a407-b6957a43a056}
+ DICUI.Library
+
\ No newline at end of file
diff --git a/DICUI/EnumDescriptionConverter.cs b/DICUI/EnumDescriptionConverter.cs
new file mode 100644
index 00000000..ffb04c9f
--- /dev/null
+++ b/DICUI/EnumDescriptionConverter.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using DICUI.Data;
+using DICUI.Utilities;
+
+namespace DICUI
+{
+ ///
+ /// Used to provide a converter to XAML files to render comboboxes with enum values
+ ///
+ public class EnumDescriptionConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is DICCommand)
+ return ((DICCommand)value).Name();
+ else if (value is DICFlag)
+ return ((DICFlag)value).Name();
+ else if (value is MediaType?)
+ return ((MediaType?)value).Name();
+ else if (value is KnownSystem?)
+ return ((KnownSystem?)value).Name();
+ else
+ return "";
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return string.Empty;
+ }
+ }
+}
diff --git a/DICUI/UI/KnownSystemComboBoxItem.cs b/DICUI/KnownSystemComboBoxItem.cs
similarity index 98%
rename from DICUI/UI/KnownSystemComboBoxItem.cs
rename to DICUI/KnownSystemComboBoxItem.cs
index d9940db2..ef91bd51 100644
--- a/DICUI/UI/KnownSystemComboBoxItem.cs
+++ b/DICUI/KnownSystemComboBoxItem.cs
@@ -2,7 +2,7 @@
using DICUI.Data;
using DICUI.Utilities;
-namespace DICUI.UI
+namespace DICUI
{
///
/// Represents a single item in the System combo box
diff --git a/DICUI/UI/ViewModels.cs b/DICUI/ViewModels.cs
similarity index 98%
rename from DICUI/UI/ViewModels.cs
rename to DICUI/ViewModels.cs
index 574769f1..1c7938d0 100644
--- a/DICUI/UI/ViewModels.cs
+++ b/DICUI/ViewModels.cs
@@ -1,7 +1,8 @@
using System;
using System.Windows.Media;
+using DICUI.Windows;
-namespace DICUI.UI
+namespace DICUI
{
public class OptionsViewModel
{
diff --git a/DICUI/LogWindow.xaml b/DICUI/Windows/LogWindow.xaml
similarity index 90%
rename from DICUI/LogWindow.xaml
rename to DICUI/Windows/LogWindow.xaml
index b2a74db5..d483079b 100644
--- a/DICUI/LogWindow.xaml
+++ b/DICUI/Windows/LogWindow.xaml
@@ -1,7 +1,7 @@
-
@@ -35,12 +35,12 @@
diff --git a/DICUI/LogWindow.xaml.cs b/DICUI/Windows/LogWindow.xaml.cs
similarity index 98%
rename from DICUI/LogWindow.xaml.cs
rename to DICUI/Windows/LogWindow.xaml.cs
index d7c4c4bd..2fdb5396 100644
--- a/DICUI/LogWindow.xaml.cs
+++ b/DICUI/Windows/LogWindow.xaml.cs
@@ -11,10 +11,8 @@ using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Media;
-using DICUI.Data;
-using DICUI.UI;
-namespace DICUI
+namespace DICUI.Windows
{
public partial class LogWindow : Window
{
@@ -131,7 +129,7 @@ namespace DICUI
public void AdjustPositionToMainWindow()
{
this.Left = _mainWindow.Left;
- this.Top = _mainWindow.Top + _mainWindow.Height + UIElements.LogWindowMarginFromMainWindow;
+ this.Top = _mainWindow.Top + _mainWindow.Height + Constants.LogWindowMarginFromMainWindow;
}
private void GracefullyTerminateProcess()
diff --git a/DICUI/MainWindow.xaml b/DICUI/Windows/MainWindow.xaml
similarity index 96%
rename from DICUI/MainWindow.xaml
rename to DICUI/Windows/MainWindow.xaml
index 67564548..5725f03e 100644
--- a/DICUI/MainWindow.xaml
+++ b/DICUI/Windows/MainWindow.xaml
@@ -1,17 +1,15 @@
-
-
+
@@ -34,7 +32,7 @@
diff --git a/DICUI/MainWindow.xaml.cs b/DICUI/Windows/MainWindow.xaml.cs
similarity index 91%
rename from DICUI/MainWindow.xaml.cs
rename to DICUI/Windows/MainWindow.xaml.cs
index 5d3ed6f2..6cde0ac9 100644
--- a/DICUI/MainWindow.xaml.cs
+++ b/DICUI/Windows/MainWindow.xaml.cs
@@ -8,11 +8,9 @@ using System.Windows.Controls;
using WinForms = System.Windows.Forms;
using DICUI.Data;
using DICUI.Utilities;
-using DICUI.UI;
-namespace DICUI
+namespace DICUI.Windows
{
-
public partial class MainWindow : Window
{
// Private UI-related variables
@@ -50,7 +48,7 @@ namespace DICUI
if (_options.OpenLogWindowAtStartup)
{
this.WindowStartupLocation = WindowStartupLocation.Manual;
- double combinedHeight = this.Height + _logWindow.Height + UIElements.LogWindowMarginFromMainWindow;
+ double combinedHeight = this.Height + _logWindow.Height + Constants.LogWindowMarginFromMainWindow;
Rectangle bounds = GetScaledCoordinates(WinForms.Screen.PrimaryScreen.WorkingArea);
this.Left = bounds.Left + (bounds.Width - this.Width) / 2;
@@ -89,17 +87,21 @@ namespace DICUI
private void StartStopButtonClick(object sender, RoutedEventArgs e)
{
// Dump or stop the dump
- if ((string)StartStopButton.Content == UIElements.StartDumping)
+ if ((string)StartStopButton.Content == Constants.StartDumping)
{
StartDumping();
}
- else if ((string)StartStopButton.Content == UIElements.StopDumping)
+ else if ((string)StartStopButton.Content == Constants.StopDumping)
{
+ ViewModels.LoggerViewModel.VerboseLogLn("Canceling dumping process...");
_env.CancelDumping();
CopyProtectScanButton.IsEnabled = true;
if (EjectWhenDoneCheckBox.IsChecked == true)
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
_env.EjectDisc();
+ }
}
}
@@ -433,9 +435,34 @@ namespace DICUI
// Check for the firmware first
// TODO: Remove this (and method) once DIC end-to-end logging becomes a thing
if (!await _env.DriveHasLatestFimrware())
+ {
+ MessageBox.Show($"DiscImageCreator has reported that drive {_env.Drive.Letter} is not updated to the most recent firmware. Please update the firmware for your drive and try again.", "Outdated Firmware", MessageBoxButton.OK, MessageBoxImage.Error);
return;
+ }
- StartStopButton.Content = UIElements.StopDumping;
+ // Validate that the user explicitly wants an inactive drive to be considered for dumping
+ if (!_env.Drive.MarkedActive)
+ {
+ MessageBoxResult mbresult = MessageBox.Show("The currently selected drive does not appear to contain a disc! Are you sure you want to continue?", "Missing Disc", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
+ if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel || mbresult == MessageBoxResult.None)
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn("Dumping aborted!");
+ return;
+ }
+ }
+
+ // If a complete dump already exists
+ if (_env.FoundAllFiles())
+ {
+ MessageBoxResult mbresult = MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
+ if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel || mbresult == MessageBoxResult.None)
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn("Dumping aborted!");
+ return;
+ }
+ }
+
+ StartStopButton.Content = Constants.StopDumping;
CopyProtectScanButton.IsEnabled = false;
StatusLabel.Content = "Beginning dumping process";
ViewModels.LoggerViewModel.VerboseLogLn("Starting dumping process..");
@@ -453,12 +480,15 @@ namespace DICUI
}
finally
{
- StartStopButton.Content = UIElements.StartDumping;
+ StartStopButton.Content = Constants.StartDumping;
CopyProtectScanButton.IsEnabled = true;
}
if (EjectWhenDoneCheckBox.IsChecked == true)
+ {
+ ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
_env.EjectDisc();
+ }
}
///
@@ -545,7 +575,7 @@ namespace DICUI
private void SetSupportedDriveSpeed()
{
// Set the drive speed list that's appropriate
- var values = AllowedSpeeds.GetForMediaType(_currentMediaType);
+ var values = Constants.GetSpeedsForMediaType(_currentMediaType);
DriveSpeedComboBox.ItemsSource = values;
ViewModels.LoggerViewModel.VerboseLogLn("Supported media speeds: {0}", string.Join(",", values));
diff --git a/DICUI/OptionsWindow.xaml b/DICUI/Windows/OptionsWindow.xaml
similarity index 94%
rename from DICUI/OptionsWindow.xaml
rename to DICUI/Windows/OptionsWindow.xaml
index cfe8ef8f..66c5770e 100644
--- a/DICUI/OptionsWindow.xaml
+++ b/DICUI/Windows/OptionsWindow.xaml
@@ -1,10 +1,9 @@
-
@@ -59,15 +58,15 @@
-
+
-
+
-
+
@@ -90,12 +89,12 @@
@@ -107,20 +106,20 @@
diff --git a/DICUI/OptionsWindow.xaml.cs b/DICUI/Windows/OptionsWindow.xaml.cs
similarity index 99%
rename from DICUI/OptionsWindow.xaml.cs
rename to DICUI/Windows/OptionsWindow.xaml.cs
index 9fea84de..afb393b9 100644
--- a/DICUI/OptionsWindow.xaml.cs
+++ b/DICUI/Windows/OptionsWindow.xaml.cs
@@ -5,7 +5,7 @@ using System.Windows.Forms;
using Button = System.Windows.Controls.Button;
using TextBox = System.Windows.Controls.TextBox;
-namespace DICUI
+namespace DICUI.Windows
{
///
/// Interaction logic for OptionsWindow.xaml
diff --git a/appveyor.yml b/appveyor.yml
index 44b5224c..3e704055 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -35,11 +35,17 @@ after_build:
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/2385718/DiscImageCreator_20180915.zip
- ps: appveyor DownloadFile http://www.rawdump.net/tools/subdump_fua_0x28.zip
- 7z e DiscImageCreator_20180915.zip -oDICUI\bin\Debug\Programs Release_ANSI\*
+- 7z e DiscImageCreator_20180915.zip -oDICUI.Forms\bin\Debug\Programs Release_ANSI\*
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug *
+- 7z e subdump_fua_0x28.zip -oDICUI.Forms\bin\Debug *
- mv DICUI\bin\Debug\subdump_fua_0x28.exe DICUI\bin\Debug\subdump.exe
+- mv DICUI.Forms\bin\Debug\subdump_fua_0x28.exe DICUI.Forms\bin\Debug\subdump.exe
- 7z a DICUI.zip DICUI\bin\Debug\*
+- 7z a DICUI-Winforms.zip DICUI.Forms\bin\Debug\*
# artifact linking
artifacts:
- path: DICUI.zip
- name: DICUI
\ No newline at end of file
+ name: DICUI
+- path: DICUI-Winforms.zip
+ name: DICUI Winforms
\ No newline at end of file