2022-04-11 10:32:03 -07:00
using System ;
2021-08-04 14:17:53 -07:00
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using System.Windows ;
using System.Windows.Controls ;
2022-04-11 10:32:03 -07:00
using BurnOutSharp ;
using MPF.Core.Data ;
using MPF.Core.Utilities ;
using MPF.Library ;
using MPF.UI.Core.ComboBoxItems ;
using MPF.UI.Core.Windows ;
2023-09-05 00:08:09 -04:00
using SabreTools.RedumpLib.Data ;
2021-08-04 14:17:53 -07:00
using WPFCustomMessageBox ;
2021-12-21 21:11:18 -08:00
using WinForms = System . Windows . Forms ;
2021-08-04 14:17:53 -07:00
2023-09-25 21:39:28 -04:00
namespace MPF.UI.Core.ViewModels
2021-08-04 14:17:53 -07:00
{
public class MainViewModel
{
#region Fields
2023-09-25 21:16:43 -04:00
/// <summary>
/// Parent MainWindow object
/// </summary>
public MainWindow Parent { get ; private set ; }
2023-09-25 21:21:51 -04:00
/// <summary>
/// LogViewModel associated with the parent window
/// </summary>
public LogViewModel Logger = > Parent . LogOutput . LogViewModel ;
2023-09-25 21:29:55 -04:00
/// <summary>
/// Access to the current options
/// </summary>
public MPF . Core . Data . Options Options
{
get = > _options ;
set
{
_options = value ;
OptionsLoader . SaveToConfig ( _options ) ;
}
}
2021-08-04 14:17:53 -07:00
/// <summary>
/// Currently selected or detected media type
/// </summary>
public MediaType ? CurrentMediaType { get ; set ; }
/// <summary>
/// Current list of drives
/// </summary>
public List < Drive > Drives { get ; set ; }
/// <summary>
/// Current dumping environment
/// </summary>
public DumpEnvironment Env { get ; set ; }
2023-09-25 21:29:55 -04:00
/// <summary>
/// Internal reference to Options
/// </summary>
private MPF . Core . Data . Options _options ;
2021-08-04 14:17:53 -07:00
#endregion
#region Lists
/// <summary>
/// Current list of supported media types
/// </summary>
public List < Element < MediaType > > MediaTypes { get ; set ; } = new List < Element < MediaType > > ( ) ;
/// <summary>
/// Current list of supported system profiles
/// </summary>
2021-08-18 22:13:38 -07:00
public List < RedumpSystemComboBoxItem > Systems { get ; set ; } = RedumpSystemComboBoxItem . GenerateElements ( ) . ToList ( ) ;
2021-08-04 14:17:53 -07:00
2023-04-11 11:15:53 -04:00
/// <summary>
/// List of available internal programs
/// </summary>
public List < Element < InternalProgram > > InternalPrograms { get ; set ; } = new List < Element < InternalProgram > > ( ) ;
2021-08-04 14:17:53 -07:00
#endregion
#region Private Event Flags
/// <summary>
/// Indicates if SelectionChanged events can be executed
/// </summary>
private bool _canExecuteSelectionChanged = false ;
#endregion
2023-09-25 21:29:55 -04:00
/// <summary>
/// Generic constructor
/// </summary>
public MainViewModel ( )
{
_options = OptionsLoader . LoadFromConfig ( ) ;
}
2021-08-04 14:17:53 -07:00
/// <summary>
/// Initialize the main window after loading
/// </summary>
2023-09-25 21:29:55 -04:00
public void Init ( MainWindow parent )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
// Set the parent window
this . Parent = parent ;
2021-08-04 14:17:53 -07:00
// Load the log output
2023-09-25 21:29:55 -04:00
this . Parent . LogPanel . IsExpanded = this . Options . OpenLogWindowAtStartup ;
2021-08-04 14:17:53 -07:00
// Disable buttons until we load fully
2023-09-25 21:16:43 -04:00
this . Parent . StartStopButton . IsEnabled = false ;
this . Parent . MediaScanButton . IsEnabled = false ;
this . Parent . UpdateVolumeLabel . IsEnabled = false ;
this . Parent . CopyProtectScanButton . IsEnabled = false ;
2021-08-04 14:17:53 -07:00
// Add the click handlers to the UI
2023-09-25 21:16:43 -04:00
AddEventHandlers ( ) ;
2021-08-04 14:17:53 -07:00
2022-01-07 13:25:46 -08:00
// Display the debug option in the menu, if necessary
2023-09-25 21:29:55 -04:00
if ( this . Options . ShowDebugViewMenuItem )
2023-09-25 21:16:43 -04:00
this . Parent . DebugViewMenuItem . Visibility = Visibility . Visible ;
2022-01-07 13:25:46 -08:00
2021-08-04 14:17:53 -07:00
// Finish initializing the rest of the values
2023-09-25 21:29:55 -04:00
InitializeUIValues ( removeEventHandlers : false , rescanDrives : true ) ;
2021-09-22 11:30:56 -07:00
// Check for updates, if necessary
2023-09-25 21:29:55 -04:00
if ( this . Options . CheckForUpdatesOnStartup )
2023-09-25 21:21:51 -04:00
CheckForUpdates ( showIfSame : false ) ;
2021-08-04 14:17:53 -07:00
}
#region Population
/// <summary>
/// Get a complete list of active disc drives and fill the combo box
/// </summary>
/// <remarks>TODO: Find a way for this to periodically run, or have it hook to a "drive change" event</remarks>
2023-09-25 21:29:55 -04:00
private void PopulateDrives ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( "Scanning for drives.." ) ;
2021-08-04 14:17:53 -07:00
// Always enable the media scan
2023-09-25 21:16:43 -04:00
this . Parent . MediaScanButton . IsEnabled = true ;
this . Parent . UpdateVolumeLabel . IsEnabled = true ;
2021-08-04 14:17:53 -07:00
2022-03-05 21:50:18 -08:00
// If we have a selected drive, keep track of it
2023-09-25 21:16:43 -04:00
char? lastSelectedDrive = ( this . Parent . DriveLetterComboBox . SelectedValue as Drive ) ? . Letter ;
2022-03-05 21:50:18 -08:00
2021-08-04 14:17:53 -07:00
// Populate the list of drives and add it to the combo box
2023-09-25 21:29:55 -04:00
Drives = Drive . CreateListOfDrives ( this . Options . IgnoreFixedDrives ) ;
2023-09-25 21:16:43 -04:00
this . Parent . DriveLetterComboBox . ItemsSource = Drives ;
2021-08-04 14:17:53 -07:00
2023-09-25 21:16:43 -04:00
if ( this . Parent . DriveLetterComboBox . Items . Count > 0 )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Found {Drives.Count} drives: {string.Join(" , ", Drives.Select(d => d.Letter))}" ) ;
2021-08-04 14:17:53 -07:00
2022-03-05 21:50:18 -08:00
// Check for the last selected drive, if possible
int index = - 1 ;
if ( lastSelectedDrive ! = null )
index = Drives . FindIndex ( d = > d . MarkedActive & & d . Letter = = lastSelectedDrive ) ;
// Check for active optical drives
if ( index = = - 1 )
index = Drives . FindIndex ( d = > d . MarkedActive & & d . InternalDriveType = = InternalDriveType . Optical ) ;
2021-08-04 14:17:53 -07:00
2022-03-05 21:50:18 -08:00
// Check for active floppy drives
2021-08-04 14:17:53 -07:00
if ( index = = - 1 )
index = Drives . FindIndex ( d = > d . MarkedActive & & d . InternalDriveType = = InternalDriveType . Floppy ) ;
2022-03-05 21:50:18 -08:00
// Check for any active drives
2021-08-04 14:17:53 -07:00
if ( index = = - 1 )
index = Drives . FindIndex ( d = > d . MarkedActive ) ;
// Set the selected index
2023-09-25 21:16:43 -04:00
this . Parent . DriveLetterComboBox . SelectedIndex = ( index ! = - 1 ? index : 0 ) ;
this . Parent . StatusLabel . Text = "Valid drive found! Choose your Media Type" ;
this . Parent . CopyProtectScanButton . IsEnabled = true ;
2021-08-04 14:17:53 -07:00
// Get the current system type
if ( index ! = - 1 )
2023-09-25 21:29:55 -04:00
DetermineSystemType ( ) ;
2021-08-04 14:17:53 -07:00
// Only enable the start/stop if we don't have the default selected
2023-09-25 21:16:43 -04:00
this . Parent . StartStopButton . IsEnabled = ShouldEnableDumpingButton ( ) ;
2021-08-04 14:17:53 -07:00
}
else
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( "Found no drives" ) ;
2023-09-25 21:16:43 -04:00
this . Parent . DriveLetterComboBox . SelectedIndex = - 1 ;
this . Parent . StatusLabel . Text = "No valid drive found!" ;
this . Parent . StartStopButton . IsEnabled = false ;
this . Parent . CopyProtectScanButton . IsEnabled = false ;
2021-08-04 14:17:53 -07:00
}
// Ensure the UI gets updated
2023-09-25 21:16:43 -04:00
this . Parent . UpdateLayout ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Populate media type according to system type
/// </summary>
2023-09-25 21:16:43 -04:00
private void PopulateMediaType ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
RedumpSystem ? currentSystem = this . Parent . SystemTypeComboBox . SelectedItem as RedumpSystemComboBoxItem ;
2021-08-04 14:17:53 -07:00
if ( currentSystem ! = null )
{
2021-08-18 22:48:31 -07:00
var mediaTypeValues = currentSystem . MediaTypes ( ) ;
2021-08-04 14:17:53 -07:00
MediaTypes = Element < MediaType > . GenerateElements ( ) . Where ( m = > mediaTypeValues . Contains ( m . Value ) ) . ToList ( ) ;
2023-09-25 21:16:43 -04:00
this . Parent . MediaTypeComboBox . ItemsSource = MediaTypes ;
2021-08-04 14:17:53 -07:00
2023-09-25 21:16:43 -04:00
this . Parent . MediaTypeComboBox . IsEnabled = MediaTypes . Count > 1 ;
2021-08-04 14:17:53 -07:00
int currentIndex = MediaTypes . FindIndex ( m = > m = = CurrentMediaType ) ;
2023-09-25 21:16:43 -04:00
this . Parent . MediaTypeComboBox . SelectedIndex = ( currentIndex > - 1 ? currentIndex : 0 ) ;
2021-08-04 14:17:53 -07:00
}
else
{
2023-09-25 21:16:43 -04:00
this . Parent . MediaTypeComboBox . IsEnabled = false ;
this . Parent . MediaTypeComboBox . ItemsSource = null ;
this . Parent . MediaTypeComboBox . SelectedIndex = - 1 ;
2021-08-04 14:17:53 -07:00
}
// Ensure the UI gets updated
2023-09-25 21:16:43 -04:00
this . Parent . UpdateLayout ( ) ;
2021-08-04 14:17:53 -07:00
}
2023-04-11 11:15:53 -04:00
/// <summary>
/// Populate media type according to system type
/// </summary>
2023-09-25 21:29:55 -04:00
private void PopulateInternalPrograms ( )
2023-04-11 11:15:53 -04:00
{
// Get the current internal program
2023-09-25 21:29:55 -04:00
InternalProgram internalProgram = this . Options . InternalProgram ;
2023-04-11 11:15:53 -04:00
// Create a static list of supported programs, not everything
2023-09-07 10:36:33 -04:00
var internalPrograms = new List < InternalProgram > { InternalProgram . DiscImageCreator , InternalProgram . Aaru , InternalProgram . Redumper } ;
2023-04-11 11:15:53 -04:00
InternalPrograms = internalPrograms . Select ( ip = > new Element < InternalProgram > ( ip ) ) . ToList ( ) ;
2023-09-25 21:16:43 -04:00
this . Parent . DumpingProgramComboBox . ItemsSource = InternalPrograms ;
2023-04-11 11:15:53 -04:00
// Select the current default dumping program
int currentIndex = InternalPrograms . FindIndex ( m = > m = = internalProgram ) ;
2023-09-25 21:16:43 -04:00
this . Parent . DumpingProgramComboBox . SelectedIndex = ( currentIndex > - 1 ? currentIndex : 0 ) ;
2023-04-11 11:15:53 -04:00
// Ensure the UI gets updated
2023-09-25 21:16:43 -04:00
this . Parent . UpdateLayout ( ) ;
2023-04-11 11:15:53 -04:00
}
2021-08-04 14:17:53 -07:00
#endregion
#region UI Commands
2023-08-26 23:17:49 -04:00
/// <summary>
/// Change the currently selected dumping program
/// </summary>
2023-09-25 21:29:55 -04:00
public void ChangeDumpingProgram ( )
2023-08-26 23:17:49 -04:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Changed dumping program to: {(this.Parent.DumpingProgramComboBox.SelectedItem as Element<InternalProgram>).Name}" ) ;
2023-09-25 21:29:55 -04:00
EnsureDiscInformation ( ) ;
GetOutputNames ( false ) ;
2023-08-26 23:17:49 -04:00
}
2021-08-04 14:17:53 -07:00
/// <summary>
/// Change the currently selected media type
/// </summary>
2023-09-25 21:29:55 -04:00
public void ChangeMediaType ( SelectionChangedEventArgs e )
2021-08-04 14:17:53 -07:00
{
// Only change the media type if the selection and not the list has changed
if ( e . RemovedItems . Count = = 1 & & e . AddedItems . Count = = 1 )
{
2023-09-25 21:16:43 -04:00
var selectedMediaType = this . Parent . MediaTypeComboBox . SelectedItem as Element < MediaType > ;
2021-08-04 14:17:53 -07:00
CurrentMediaType = selectedMediaType . Value ;
2023-09-25 21:29:55 -04:00
SetSupportedDriveSpeed ( ) ;
2021-08-04 14:17:53 -07:00
}
2023-09-25 21:29:55 -04:00
GetOutputNames ( false ) ;
EnsureDiscInformation ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Change the currently selected system
/// </summary>
2023-09-25 21:29:55 -04:00
public void ChangeSystem ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Changed system to: {(this.Parent.SystemTypeComboBox.SelectedItem as RedumpSystemComboBoxItem).Name}" ) ;
2023-09-25 21:16:43 -04:00
PopulateMediaType ( ) ;
2023-09-25 21:29:55 -04:00
GetOutputNames ( false ) ;
EnsureDiscInformation ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Check for available updates
/// </summary>
2021-12-30 21:00:01 -08:00
/// <param name="showIfSame">True to show the box even if it's the same, false to only show if it's different</param>
2023-09-25 21:21:51 -04:00
public void CheckForUpdates ( bool showIfSame )
2021-08-04 14:17:53 -07:00
{
( bool different , string message , string url ) = Tools . CheckForNewVersion ( ) ;
// If we have a new version, put it in the clipboard
if ( different )
Clipboard . SetText ( url ) ;
2023-09-25 21:21:51 -04:00
this . Logger . SecretLogLn ( message ) ;
2021-09-28 11:46:37 -07:00
if ( url = = null )
message = "An exception occurred while checking for versions, please try again later. See the log window for more details." ;
2021-12-30 21:00:01 -08:00
if ( showIfSame | | different )
2023-09-25 21:16:43 -04:00
CustomMessageBox . Show ( message , "Version Update Check" , MessageBoxButton . OK , different ? MessageBoxImage . Exclamation : MessageBoxImage . Information ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Shutdown the current application
/// </summary>
2023-09-25 21:39:28 -04:00
public static void ExitApplication ( ) = > Application . Current . Shutdown ( ) ;
2021-08-04 14:17:53 -07:00
/// <summary>
2022-12-13 11:48:26 -08:00
/// Set the output path from a dialog box
2021-08-04 14:17:53 -07:00
/// </summary>
2023-09-25 21:29:55 -04:00
public void SetOutputPath ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
BrowseFile ( ) ;
EnsureDiscInformation ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Show the About text popup
/// </summary>
2023-09-25 21:21:51 -04:00
public void ShowAboutText ( )
2021-08-04 14:17:53 -07:00
{
string aboutText = $"Media Preservation Frontend (MPF)"
+ $"{Environment.NewLine}"
+ $"{Environment.NewLine}A community preservation frontend developed in C#."
2023-09-07 10:36:33 -04:00
+ $"{Environment.NewLine}Supports Redumper, Aaru, and DiscImageCreator."
2021-08-04 14:17:53 -07:00
+ $"{Environment.NewLine}Originally created to help the Redump project."
+ $"{Environment.NewLine}"
+ $"{Environment.NewLine}Thanks to everyone who has supported this project!"
+ $"{Environment.NewLine}"
+ $"{Environment.NewLine}Version {Tools.GetCurrentVersion()}" ;
2023-09-25 21:21:51 -04:00
this . Logger . SecretLogLn ( aboutText ) ;
2023-09-25 21:16:43 -04:00
CustomMessageBox . Show ( aboutText , "About" , MessageBoxButton . OK , MessageBoxImage . Information ) ;
2021-08-04 14:17:53 -07:00
}
2022-01-07 13:25:46 -08:00
/// <summary>
/// Build a dummy SubmissionInfo and display it for testing
/// </summary>
public void ShowDebugDiscInfoWindow ( )
{
var submissionInfo = new SubmissionInfo ( )
{
SchemaVersion = 1 ,
2022-03-12 21:09:51 -08:00
FullyMatchedID = 3 ,
PartiallyMatchedIDs = new List < int > { 0 , 1 , 2 , 3 } ,
2022-01-07 13:25:46 -08:00
Added = DateTime . UtcNow ,
LastModified = DateTime . UtcNow ,
CommonDiscInfo = new CommonDiscInfoSection ( )
{
System = RedumpSystem . IBMPCcompatible ,
2022-04-04 21:46:13 -07:00
Media = DiscType . BD128 ,
2022-01-07 13:25:46 -08:00
Title = "Game Title" ,
ForeignTitleNonLatin = "Foreign Game Title" ,
DiscNumberLetter = "1" ,
DiscTitle = "Install Disc" ,
Category = DiscCategory . Games ,
Region = Region . World ,
Languages = new Language ? [ ] { Language . English , Language . Spanish , Language . French } ,
LanguageSelection = new LanguageSelection ? [ ] { LanguageSelection . BiosSettings } ,
Serial = "Disc Serial" ,
Layer0MasteringRing = "L0 Mastering Ring" ,
Layer0MasteringSID = "L0 Mastering SID" ,
Layer0ToolstampMasteringCode = "L0 Toolstamp" ,
Layer0MouldSID = "L0 Mould SID" ,
Layer0AdditionalMould = "L0 Additional Mould" ,
Layer1MasteringRing = "L1 Mastering Ring" ,
Layer1MasteringSID = "L1 Mastering SID" ,
Layer1ToolstampMasteringCode = "L1 Toolstamp" ,
Layer1MouldSID = "L1 Mould SID" ,
Layer1AdditionalMould = "L1 Additional Mould" ,
Layer2MasteringRing = "L2 Mastering Ring" ,
Layer2MasteringSID = "L2 Mastering SID" ,
Layer2ToolstampMasteringCode = "L2 Toolstamp" ,
Layer3MasteringRing = "L3 Mastering Ring" ,
Layer3MasteringSID = "L3 Mastering SID" ,
Layer3ToolstampMasteringCode = "L3 Toolstamp" ,
RingWriteOffset = "+12" ,
Barcode = "UPC Barcode" ,
EXEDateBuildDate = "19xx-xx-xx" ,
ErrorsCount = "0" ,
Comments = "Comment data line 1\r\nComment data line 2" ,
2023-09-05 00:08:09 -04:00
#if NET48
2022-01-07 13:25:46 -08:00
CommentsSpecialFields = new Dictionary < SiteCode ? , string > ( )
2023-09-05 00:08:09 -04:00
#else
CommentsSpecialFields = new Dictionary < SiteCode , string > ( )
#endif
2022-01-07 13:25:46 -08:00
{
[SiteCode.ISBN] = "ISBN" ,
} ,
Contents = "Special contents 1\r\nSpecial contents 2" ,
2023-09-05 00:08:09 -04:00
#if NET48
2022-01-07 13:25:46 -08:00
ContentsSpecialFields = new Dictionary < SiteCode ? , string > ( )
2023-09-05 00:08:09 -04:00
#else
ContentsSpecialFields = new Dictionary < SiteCode , string > ( )
#endif
2022-01-07 13:25:46 -08:00
{
[SiteCode.PlayableDemos] = "Game Demo 1" ,
} ,
} ,
VersionAndEditions = new VersionAndEditionsSection ( )
{
Version = "Original" ,
VersionDatfile = "Alt" ,
CommonEditions = new string [ ] { "Taikenban" } ,
OtherEditions = "Rerelease" ,
} ,
EDC = new EDCSection ( )
{
EDC = YesNo . Yes ,
} ,
ParentCloneRelationship = new ParentCloneRelationshipSection ( )
{
ParentID = "12345" ,
RegionalParent = false ,
} ,
Extras = new ExtrasSection ( )
{
PVD = "PVD with a stupidly long line and nothing else but a little more\nPVD with a stupidly long line and nothing else but a little more\nPVD with a stupidly long line and nothing else but a little more\nPVD with a stupidly long line and nothing else but a little more\nPVD with a stupidly long line and nothing else but a little more\nPVD with a stupidly long line and nothing else but a little more\n" ,
DiscKey = "Disc key" ,
DiscID = "Disc ID" ,
PIC = "PIC" ,
Header = "Header" ,
BCA = "BCA" ,
SecuritySectorRanges = "SSv1 Ranges" ,
} ,
CopyProtection = new CopyProtectionSection ( )
{
AntiModchip = YesNo . Yes ,
LibCrypt = YesNo . No ,
LibCryptData = "LibCrypt data" ,
Protection = "List of protections" ,
SecuROMData = "SecuROM data" ,
} ,
DumpersAndStatus = new DumpersAndStatusSection ( )
{
2022-04-04 21:46:13 -07:00
Status = DumpStatus . TwoOrMoreGreen ,
2022-01-07 13:25:46 -08:00
Dumpers = new string [ ] { "Dumper1" , "Dumper2" } ,
OtherDumpers = "Dumper3" ,
} ,
TracksAndWriteOffsets = new TracksAndWriteOffsetsSection ( )
{
ClrMameProData = "Datfile" ,
Cuesheet = "Cuesheet" ,
CommonWriteOffsets = new int [ ] { 0 , 12 , - 12 } ,
OtherWriteOffsets = "-2" ,
} ,
SizeAndChecksums = new SizeAndChecksumsSection ( )
{
Layerbreak = 0 ,
Layerbreak2 = 1 ,
Layerbreak3 = 2 ,
Size = 12345 ,
CRC32 = "CRC32" ,
MD5 = "MD5" ,
SHA1 = "SHA1" ,
} ,
2022-10-17 20:56:28 -07:00
DumpingInfo = new DumpingInfoSection ( )
{
DumpingProgram = "DiscImageCreator 20500101" ,
2023-09-18 21:36:29 +02:00
DumpingDate = DateTime . UtcNow . ToString ( "yyyy-MM-dd HH:mm:ss" ) ,
2022-10-17 20:56:28 -07:00
Manufacturer = "ATAPI" ,
Model = "Optical Drive" ,
Firmware = "1.23" ,
2022-10-19 12:34:40 -07:00
ReportedDiscType = "CD-R" ,
2022-10-17 20:56:28 -07:00
} ,
2022-01-07 13:25:46 -08:00
Artifacts = new Dictionary < string , string > ( )
{
["Sample Artifact"] = "Sample Data" ,
} ,
} ;
var result = ShowDiscInformationWindow ( submissionInfo ) ;
InfoTool . ProcessSpecialFields ( result . Item2 ) ;
}
2021-08-04 14:17:53 -07:00
/// <summary>
/// Show the Options window
/// </summary>
2023-09-25 21:29:55 -04:00
public void ShowOptionsWindow ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
var optionsWindow = new OptionsWindow ( this . Options ) { Owner = this . Parent } ;
2021-08-04 14:17:53 -07:00
optionsWindow . Closed + = OnOptionsUpdated ;
optionsWindow . Show ( ) ;
}
/// <summary>
/// Toggle the parameters input box
/// </summary>
2023-09-25 21:16:43 -04:00
public void ToggleParameters ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
if ( this . Parent . EnableParametersCheckBox . IsChecked = = true )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
this . Parent . SystemTypeComboBox . IsEnabled = false ;
this . Parent . MediaTypeComboBox . IsEnabled = false ;
2023-03-04 22:40:10 -05:00
2023-09-25 21:16:43 -04:00
this . Parent . OutputPathTextBox . IsEnabled = false ;
this . Parent . OutputPathBrowseButton . IsEnabled = false ;
2022-12-30 11:24:51 -08:00
2023-09-25 21:16:43 -04:00
this . Parent . MediaScanButton . IsEnabled = false ;
this . Parent . UpdateVolumeLabel . IsEnabled = false ;
this . Parent . CopyProtectScanButton . IsEnabled = false ;
2022-12-30 11:24:51 -08:00
2023-09-25 21:16:43 -04:00
this . Parent . ParametersTextBox . IsEnabled = true ;
2021-08-04 14:17:53 -07:00
}
else
{
2023-09-25 21:16:43 -04:00
this . Parent . ParametersTextBox . IsEnabled = false ;
ProcessCustomParameters ( ) ;
2022-12-30 11:24:51 -08:00
2023-09-25 21:16:43 -04:00
this . Parent . SystemTypeComboBox . IsEnabled = true ;
this . Parent . MediaTypeComboBox . IsEnabled = true ;
2023-03-04 22:40:10 -05:00
2023-09-25 21:16:43 -04:00
this . Parent . OutputPathTextBox . IsEnabled = true ;
this . Parent . OutputPathBrowseButton . IsEnabled = true ;
2022-12-30 11:24:51 -08:00
2023-09-25 21:16:43 -04:00
this . Parent . MediaScanButton . IsEnabled = true ;
this . Parent . UpdateVolumeLabel . IsEnabled = true ;
this . Parent . CopyProtectScanButton . IsEnabled = true ;
2021-08-04 14:17:53 -07:00
}
}
/// <summary>
/// Toggle the Start/Stop button
/// </summary>
2023-09-25 21:29:55 -04:00
public async void ToggleStartStop ( )
2021-08-04 14:17:53 -07:00
{
// Dump or stop the dump
2023-09-25 21:16:43 -04:00
if ( ( string ) this . Parent . StartStopButton . Content = = Interface . StartDumping )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
StartDumping ( ) ;
2021-08-04 14:17:53 -07:00
}
2023-09-25 21:16:43 -04:00
else if ( ( string ) this . Parent . StartStopButton . Content = = Interface . StopDumping )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( "Canceling dumping process..." ) ;
2021-08-04 14:17:53 -07:00
Env . CancelDumping ( ) ;
2023-09-25 21:16:43 -04:00
this . Parent . CopyProtectScanButton . IsEnabled = true ;
2021-08-04 14:17:53 -07:00
if ( Env . Options . EjectAfterDump = = true )
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Ejecting disc in drive {Env.Drive.Letter}" ) ;
2021-11-26 14:06:57 -08:00
await Env . EjectDisc ( ) ;
2021-08-04 14:17:53 -07:00
}
2023-09-25 21:29:55 -04:00
if ( this . Options . DICResetDriveAfterDump )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Resetting drive {Env.Drive.Letter}" ) ;
2021-11-26 14:06:57 -08:00
await Env . ResetDrive ( ) ;
2021-08-04 14:17:53 -07:00
}
}
// Reset the progress bar
2023-09-25 21:21:51 -04:00
this . Logger . ResetProgressBar ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Update the internal options from a closed OptionsWindow
/// </summary>
/// <param name="optionsWindow">OptionsWindow to copy back data from</param>
2023-09-25 21:29:55 -04:00
public void UpdateOptions ( OptionsWindow optionsWindow )
2021-08-04 14:17:53 -07:00
{
if ( optionsWindow ? . OptionsViewModel . SavedSettings = = true )
{
2023-09-26 21:27:36 -04:00
this . Options = new MPF . Core . Data . Options ( optionsWindow . OptionsViewModel . Options ) ;
2023-09-25 21:29:55 -04:00
InitializeUIValues ( removeEventHandlers : true , rescanDrives : true ) ;
2021-08-04 14:17:53 -07:00
}
}
2023-09-25 15:36:50 -04:00
#endregion
2021-08-04 14:17:53 -07:00
#region UI Functionality
/// <summary>
/// Performs UI value setup end to end
/// </summary>
/// <param name="removeEventHandlers">Whether event handlers need to be removed first</param>
/// <param name="rescanDrives">Whether drives should be rescanned or not</param>
2023-09-25 21:29:55 -04:00
public async void InitializeUIValues ( bool removeEventHandlers , bool rescanDrives )
2021-08-04 14:17:53 -07:00
{
// Disable the dumping button
2023-09-25 21:16:43 -04:00
this . Parent . StartStopButton . IsEnabled = false ;
2021-12-21 21:11:18 -08:00
2021-11-08 20:45:37 -08:00
// Safely uncheck the parameters box, just in case
2023-09-25 21:16:43 -04:00
if ( this . Parent . EnableParametersCheckBox . IsChecked = = true )
2021-11-08 20:45:37 -08:00
{
2023-09-25 21:16:43 -04:00
this . Parent . EnableParametersCheckBox . Checked - = EnableParametersCheckBoxClick ;
this . Parent . EnableParametersCheckBox . IsChecked = false ;
this . Parent . ParametersTextBox . IsEnabled = false ;
this . Parent . EnableParametersCheckBox . Checked + = EnableParametersCheckBoxClick ;
2021-11-08 20:45:37 -08:00
}
2021-08-04 14:17:53 -07:00
// Set the UI color scheme according to the options
2023-09-25 21:29:55 -04:00
if ( this . Options . EnableDarkMode )
2021-08-04 14:17:53 -07:00
EnableDarkMode ( ) ;
else
2023-04-26 09:51:29 -04:00
EnableLightMode ( ) ;
2021-08-04 14:17:53 -07:00
// Force the UI to reload after applying the theme
2023-09-25 21:16:43 -04:00
this . Parent . UpdateLayout ( ) ;
2021-08-04 14:17:53 -07:00
// Remove event handlers to ensure ordering
if ( removeEventHandlers )
DisableEventHandlers ( ) ;
// Populate the list of drives and determine the system
if ( rescanDrives )
{
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = "Creating drive list, please wait!" ;
2023-09-25 21:29:55 -04:00
await this . Parent . Dispatcher . InvokeAsync ( ( ) = > PopulateDrives ( ) ) ;
2021-08-04 14:17:53 -07:00
}
else
{
2023-09-25 21:29:55 -04:00
await this . Parent . Dispatcher . InvokeAsync ( ( ) = > DetermineSystemType ( ) ) ;
2021-08-04 14:17:53 -07:00
}
// Determine current media type, if possible
2023-09-25 21:16:43 -04:00
await this . Parent . Dispatcher . InvokeAsync ( ( ) = > PopulateMediaType ( ) ) ;
2023-09-25 21:29:55 -04:00
CacheCurrentDiscType ( ) ;
2023-09-25 21:16:43 -04:00
SetCurrentDiscType ( ) ;
2021-08-04 14:17:53 -07:00
2023-04-11 11:15:53 -04:00
// Set the dumping program
2023-09-25 21:29:55 -04:00
await this . Parent . Dispatcher . InvokeAsync ( ( ) = > PopulateInternalPrograms ( ) ) ;
2023-04-11 11:15:53 -04:00
2021-08-04 14:17:53 -07:00
// Set the initial environment and UI values
2023-09-25 21:29:55 -04:00
SetSupportedDriveSpeed ( ) ;
Env = DetermineEnvironment ( ) ;
GetOutputNames ( true ) ;
EnsureDiscInformation ( ) ;
2021-08-04 14:17:53 -07:00
// Enable event handlers
EnableEventHandlers ( ) ;
// Enable the dumping button, if necessary
2023-09-25 21:16:43 -04:00
this . Parent . StartStopButton . IsEnabled = ShouldEnableDumpingButton ( ) ;
2021-08-04 14:17:53 -07:00
}
2023-03-04 22:40:10 -05:00
/// <summary>
/// Performs a fast update of the output path while skipping disc checks
/// </summary>
/// <param name="removeEventHandlers">Whether event handlers need to be removed first</param>
2023-09-25 21:29:55 -04:00
private void FastUpdateLabel ( bool removeEventHandlers )
2023-03-04 22:40:10 -05:00
{
// Disable the dumping button
2023-09-25 21:16:43 -04:00
this . Parent . StartStopButton . IsEnabled = false ;
2023-03-04 22:40:10 -05:00
// Safely uncheck the parameters box, just in case
2023-09-25 21:16:43 -04:00
if ( this . Parent . EnableParametersCheckBox . IsChecked = = true )
2023-03-04 22:40:10 -05:00
{
2023-09-25 21:16:43 -04:00
this . Parent . EnableParametersCheckBox . Checked - = EnableParametersCheckBoxClick ;
this . Parent . EnableParametersCheckBox . IsChecked = false ;
this . Parent . ParametersTextBox . IsEnabled = false ;
this . Parent . EnableParametersCheckBox . Checked + = EnableParametersCheckBoxClick ;
2023-03-04 22:40:10 -05:00
}
// Remove event handlers to ensure ordering
if ( removeEventHandlers )
DisableEventHandlers ( ) ;
// Refresh the drive info
2023-09-25 21:16:43 -04:00
( this . Parent . DriveLetterComboBox . SelectedItem as Drive ) ? . RefreshDrive ( ) ;
2023-03-04 22:40:10 -05:00
// Set the initial environment and UI values
2023-09-25 21:29:55 -04:00
Env = DetermineEnvironment ( ) ;
GetOutputNames ( true ) ;
EnsureDiscInformation ( ) ;
2023-03-04 22:40:10 -05:00
// Enable event handlers
EnableEventHandlers ( ) ;
// Enable the dumping button, if necessary
2023-09-25 21:16:43 -04:00
this . Parent . StartStopButton . IsEnabled = ShouldEnableDumpingButton ( ) ;
2023-03-04 22:40:10 -05:00
}
2021-08-04 14:17:53 -07:00
/// <summary>
/// Add all event handlers
/// </summary>
2023-09-25 21:16:43 -04:00
private void AddEventHandlers ( )
2021-08-04 14:17:53 -07:00
{
// Menu Bar Click
2023-09-25 21:16:43 -04:00
this . Parent . AboutMenuItem . Click + = AboutClick ;
this . Parent . AppExitMenuItem . Click + = AppExitClick ;
this . Parent . CheckForUpdatesMenuItem . Click + = CheckForUpdatesClick ;
this . Parent . DebugViewMenuItem . Click + = DebugViewClick ;
this . Parent . OptionsMenuItem . Click + = OptionsMenuItemClick ;
2021-08-04 14:17:53 -07:00
// User Area Click
2023-09-25 21:16:43 -04:00
this . Parent . CopyProtectScanButton . Click + = CopyProtectScanButtonClick ;
this . Parent . EnableParametersCheckBox . Click + = EnableParametersCheckBoxClick ;
this . Parent . MediaScanButton . Click + = MediaScanButtonClick ;
this . Parent . UpdateVolumeLabel . Click + = UpdateVolumeLabelClick ;
this . Parent . OutputPathBrowseButton . Click + = OutputPathBrowseButtonClick ;
this . Parent . StartStopButton . Click + = StartStopButtonClick ;
2021-08-04 14:17:53 -07:00
// User Area SelectionChanged
2023-09-25 21:16:43 -04:00
this . Parent . SystemTypeComboBox . SelectionChanged + = SystemTypeComboBoxSelectionChanged ;
this . Parent . MediaTypeComboBox . SelectionChanged + = MediaTypeComboBoxSelectionChanged ;
this . Parent . DriveLetterComboBox . SelectionChanged + = DriveLetterComboBoxSelectionChanged ;
this . Parent . DriveSpeedComboBox . SelectionChanged + = DriveSpeedComboBoxSelectionChanged ;
this . Parent . DumpingProgramComboBox . SelectionChanged + = DumpingProgramComboBoxSelectionChanged ;
2022-12-30 10:59:32 -08:00
// User Area TextChanged
2023-09-25 21:16:43 -04:00
this . Parent . OutputPathTextBox . TextChanged + = OutputPathTextBoxTextChanged ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Enable all textbox and combobox event handlers
/// </summary>
private void EnableEventHandlers ( )
{
_canExecuteSelectionChanged = true ;
}
/// <summary>
/// Disable all textbox and combobox event handlers
/// </summary>
private void DisableEventHandlers ( )
{
_canExecuteSelectionChanged = false ;
}
/// <summary>
/// Disable all UI elements during dumping
/// </summary>
2023-09-25 21:16:43 -04:00
private void DisableAllUIElements ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
this . Parent . OptionsMenuItem . IsEnabled = false ;
this . Parent . SystemTypeComboBox . IsEnabled = false ;
this . Parent . MediaTypeComboBox . IsEnabled = false ;
this . Parent . OutputPathTextBox . IsEnabled = false ;
this . Parent . OutputPathBrowseButton . IsEnabled = false ;
this . Parent . DriveLetterComboBox . IsEnabled = false ;
this . Parent . DriveSpeedComboBox . IsEnabled = false ;
this . Parent . DumpingProgramComboBox . IsEnabled = false ;
this . Parent . EnableParametersCheckBox . IsEnabled = false ;
this . Parent . StartStopButton . Content = Interface . StopDumping ;
this . Parent . MediaScanButton . IsEnabled = false ;
this . Parent . UpdateVolumeLabel . IsEnabled = false ;
this . Parent . CopyProtectScanButton . IsEnabled = false ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Enable all UI elements after dumping
/// </summary>
2023-09-25 21:16:43 -04:00
private void EnableAllUIElements ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
this . Parent . OptionsMenuItem . IsEnabled = true ;
this . Parent . SystemTypeComboBox . IsEnabled = true ;
this . Parent . MediaTypeComboBox . IsEnabled = true ;
this . Parent . OutputPathTextBox . IsEnabled = true ;
this . Parent . OutputPathBrowseButton . IsEnabled = true ;
this . Parent . DriveLetterComboBox . IsEnabled = true ;
this . Parent . DriveSpeedComboBox . IsEnabled = true ;
this . Parent . DumpingProgramComboBox . IsEnabled = true ;
this . Parent . EnableParametersCheckBox . IsEnabled = true ;
this . Parent . StartStopButton . Content = Interface . StartDumping ;
this . Parent . MediaScanButton . IsEnabled = true ;
this . Parent . UpdateVolumeLabel . IsEnabled = true ;
this . Parent . CopyProtectScanButton . IsEnabled = true ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
2023-04-26 09:51:29 -04:00
/// Recolor all UI elements for light mode
2021-08-04 14:17:53 -07:00
/// </summary>
2023-09-25 21:39:28 -04:00
private static void EnableLightMode ( )
2021-08-04 14:17:53 -07:00
{
2023-04-26 09:51:29 -04:00
var theme = new LightModeTheme ( ) ;
theme . Apply ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Recolor all UI elements for dark mode
/// </summary>
2023-09-25 21:39:28 -04:00
private static void EnableDarkMode ( )
2021-08-04 14:17:53 -07:00
{
2023-04-26 09:51:29 -04:00
var theme = new DarkModeTheme ( ) ;
theme . Apply ( ) ;
2021-08-04 14:17:53 -07:00
}
#endregion
#region Helpers
/// <summary>
2022-12-13 11:48:26 -08:00
/// Browse for an output file path
2021-08-04 14:17:53 -07:00
/// </summary>
2023-09-25 21:29:55 -04:00
private void BrowseFile ( )
2021-08-04 14:17:53 -07:00
{
2022-12-13 11:48:26 -08:00
// Get the current path, if possible
2023-09-25 21:16:43 -04:00
string currentPath = this . Parent . OutputPathTextBox . Text ;
2022-12-13 11:48:26 -08:00
if ( string . IsNullOrWhiteSpace ( currentPath ) )
2023-09-25 21:29:55 -04:00
currentPath = Path . Combine ( this . Options . DefaultOutputPath , "track.bin" ) ;
2022-12-13 11:48:26 -08:00
if ( string . IsNullOrWhiteSpace ( currentPath ) )
currentPath = Path . Combine ( System . AppDomain . CurrentDomain . BaseDirectory , "track.bin" ) ;
2022-10-04 20:45:28 -07:00
2022-12-13 11:48:26 -08:00
// Get the full path
currentPath = Path . GetFullPath ( currentPath ) ;
// Get the directory
string directory = Path . GetDirectoryName ( currentPath ) ;
// Get the filename
string filename = Path . GetFileName ( currentPath ) ;
WinForms . FileDialog fileDialog = new WinForms . SaveFileDialog
2022-10-04 20:45:28 -07:00
{
2022-12-13 11:48:26 -08:00
FileName = filename ,
InitialDirectory = directory ,
2022-10-04 20:45:28 -07:00
} ;
2022-12-13 11:48:26 -08:00
WinForms . DialogResult result = fileDialog . ShowDialog ( ) ;
2021-08-04 14:17:53 -07:00
if ( result = = WinForms . DialogResult . OK )
{
2023-09-25 21:16:43 -04:00
this . Parent . OutputPathTextBox . Text = fileDialog . FileName ;
2021-08-04 14:17:53 -07:00
}
}
/// <summary>
/// Cache the current disc type to internal variable
/// </summary>
2023-09-25 21:29:55 -04:00
private void CacheCurrentDiscType ( )
2021-08-04 14:17:53 -07:00
{
// If the selected item is invalid, we just skip
2023-09-25 21:16:43 -04:00
if ( ! ( this . Parent . DriveLetterComboBox . SelectedItem is Drive drive ) )
2021-08-04 14:17:53 -07:00
return ;
// Get reasonable default values based on the current system
2023-09-25 21:16:43 -04:00
RedumpSystem ? currentSystem = Systems [ this . Parent . SystemTypeComboBox . SelectedIndex ] ;
2021-08-18 22:48:31 -07:00
MediaType ? defaultMediaType = currentSystem . MediaTypes ( ) . FirstOrDefault ( ) ? ? MediaType . CDROM ;
2021-08-04 14:17:53 -07:00
if ( defaultMediaType = = MediaType . NONE )
defaultMediaType = MediaType . CDROM ;
2023-09-25 15:36:50 -04:00
#if NET48 | | NETSTANDARD2_1
2021-08-04 14:17:53 -07:00
// If we're skipping detection, set the default value
2023-09-25 21:29:55 -04:00
if ( this . Options . SkipMediaTypeDetection )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Media type detection disabled, defaulting to {defaultMediaType.LongName()}." ) ;
2021-08-04 14:17:53 -07:00
CurrentMediaType = defaultMediaType ;
}
// If the drive is marked active, try to read from it
else if ( drive . MarkedActive )
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLog ( $"Trying to detect media type for drive {drive.Letter} [{drive.DriveFormat}].. " ) ;
2021-09-29 16:37:28 -07:00
( MediaType ? detectedMediaType , string errorMessage ) = drive . GetMediaType ( ) ;
2021-08-04 14:17:53 -07:00
// If we got an error message, post it to the log
2023-09-25 21:29:55 -04:00
if ( errorMessage ! = null & & this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Message from detecting media type: {errorMessage}" ) ;
2021-08-04 14:17:53 -07:00
// If we got either an error or no media, default to the current System default
if ( detectedMediaType = = null )
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Unable to detect, defaulting to {defaultMediaType.LongName()}." ) ;
2021-08-04 14:17:53 -07:00
CurrentMediaType = defaultMediaType ;
}
else
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Detected {CurrentMediaType.LongName()}." ) ;
2021-08-04 14:17:53 -07:00
CurrentMediaType = detectedMediaType ;
}
}
// All other cases, just use the default
else
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Drive marked as empty, defaulting to {defaultMediaType.LongName()}." ) ;
2021-08-04 14:17:53 -07:00
CurrentMediaType = defaultMediaType ;
}
2023-07-17 13:23:00 -04:00
#else
// Media type detection on initialize is always disabled
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Media type detection not available, defaulting to {defaultMediaType.LongName()}." ) ;
2023-07-17 13:23:00 -04:00
CurrentMediaType = defaultMediaType ;
#endif
2021-08-04 14:17:53 -07:00
// Ensure the UI gets updated
2023-09-25 21:16:43 -04:00
this . Parent . UpdateLayout ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Create a DumpEnvironment with all current settings
/// </summary>
2023-09-25 21:16:43 -04:00
/// <returns>Filled DumpEnvironment this.Parent</returns>
2023-09-25 21:29:55 -04:00
private DumpEnvironment DetermineEnvironment ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
return new DumpEnvironment ( this . Options ,
2023-09-25 21:16:43 -04:00
this . Parent . OutputPathTextBox . Text ,
this . Parent . DriveLetterComboBox . SelectedItem as Drive ,
this . Parent . SystemTypeComboBox . SelectedItem as RedumpSystemComboBoxItem ,
this . Parent . MediaTypeComboBox . SelectedItem as Element < MediaType > ,
this . Parent . DumpingProgramComboBox . SelectedItem as Element < InternalProgram > ,
this . Parent . ParametersTextBox . Text ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
2023-02-23 16:50:00 -05:00
/// Determine and set the current system type, if allowed
2021-08-04 14:17:53 -07:00
/// </summary>
2023-09-25 21:29:55 -04:00
private void DetermineSystemType ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
if ( Drives = = null | | Drives . Count = = 0 | | this . Parent . DriveLetterComboBox . SelectedIndex = = - 1 )
2023-02-23 16:50:00 -05:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLog ( "Skipping system type detection because no valid drives found!" ) ;
2023-02-23 16:50:00 -05:00
}
2023-09-25 21:29:55 -04:00
else if ( ! this . Options . SkipSystemDetection )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLog ( $"Trying to detect system for drive {Drives[this.Parent.DriveLetterComboBox.SelectedIndex].Letter}.. " ) ;
2023-09-25 21:29:55 -04:00
var currentSystem = Drives [ this . Parent . DriveLetterComboBox . SelectedIndex ] ? . GetRedumpSystem ( this . Options . DefaultSystem ) ? ? this . Options . DefaultSystem ;
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( currentSystem = = null ? "unable to detect." : ( $"detected {currentSystem.LongName()}." ) ) ;
2021-08-04 14:17:53 -07:00
2021-08-18 22:13:38 -07:00
if ( currentSystem ! = null )
2021-08-04 14:17:53 -07:00
{
int sysIndex = Systems . FindIndex ( s = > s = = currentSystem ) ;
2023-09-25 21:16:43 -04:00
this . Parent . SystemTypeComboBox . SelectedIndex = sysIndex ;
2021-08-04 14:17:53 -07:00
}
}
2023-09-25 21:29:55 -04:00
else if ( this . Options . SkipSystemDetection & & this . Options . DefaultSystem ! = null )
2021-12-21 21:11:18 -08:00
{
2023-09-25 21:29:55 -04:00
var currentSystem = this . Options . DefaultSystem ;
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLog ( $"System detection disabled, setting to default of {currentSystem.LongName()}." ) ;
2021-12-21 21:11:18 -08:00
int sysIndex = Systems . FindIndex ( s = > s = = currentSystem ) ;
2023-09-25 21:16:43 -04:00
this . Parent . SystemTypeComboBox . SelectedIndex = sysIndex ;
2021-12-21 21:11:18 -08:00
}
2021-08-04 14:17:53 -07:00
// Ensure the UI gets updated
2023-09-25 21:16:43 -04:00
this . Parent . UpdateLayout ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Ensure information is consistent with the currently selected disc type
/// </summary>
2023-09-25 21:29:55 -04:00
public void EnsureDiscInformation ( )
2021-08-04 14:17:53 -07:00
{
// Get the current environment information
2023-09-25 21:29:55 -04:00
Env = DetermineEnvironment ( ) ;
2021-08-04 14:17:53 -07:00
// Get the status to write out
2021-09-29 11:48:37 -07:00
Result result = Tools . GetSupportStatus ( Env . System , Env . Type ) ;
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = result . Message ;
2021-08-04 14:17:53 -07:00
// Set the index for the current disc type
2023-09-25 21:16:43 -04:00
SetCurrentDiscType ( ) ;
2021-08-04 14:17:53 -07:00
// Enable or disable the button
2023-09-25 21:16:43 -04:00
this . Parent . StartStopButton . IsEnabled = result & & ShouldEnableDumpingButton ( ) ;
2021-08-04 14:17:53 -07:00
// If we're in a type that doesn't support drive speeds
2023-09-25 21:16:43 -04:00
this . Parent . DriveSpeedComboBox . IsEnabled = Env . Type . DoesSupportDriveSpeed ( ) ;
2021-08-04 14:17:53 -07:00
// If input params are not enabled, generate the full parameters from the environment
2023-09-25 21:16:43 -04:00
if ( ! this . Parent . ParametersTextBox . IsEnabled )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
string generated = Env . GetFullParameters ( ( int? ) this . Parent . DriveSpeedComboBox . SelectedItem ) ;
2021-08-04 14:17:53 -07:00
if ( generated ! = null )
2023-09-25 21:16:43 -04:00
this . Parent . ParametersTextBox . Text = generated ;
2021-08-04 14:17:53 -07:00
}
// Ensure the UI gets updated
2023-09-25 21:16:43 -04:00
this . Parent . UpdateLayout ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Get the default output directory name from the currently selected drive
/// </summary>
/// <param name="driveChanged">Force an updated name if the drive letter changes</param>
2023-09-25 21:29:55 -04:00
public void GetOutputNames ( bool driveChanged )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
if ( Drives = = null | | Drives . Count = = 0 | | this . Parent . DriveLetterComboBox . SelectedIndex = = - 1 )
2023-02-23 16:50:00 -05:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLog ( "Skipping output name building because no valid drives found!" ) ;
2023-02-23 16:50:00 -05:00
return ;
}
2023-09-25 21:16:43 -04:00
Drive drive = this . Parent . DriveLetterComboBox . SelectedItem as Drive ;
RedumpSystem ? systemType = this . Parent . SystemTypeComboBox . SelectedItem as RedumpSystemComboBoxItem ;
MediaType ? mediaType = this . Parent . MediaTypeComboBox . SelectedItem as Element < MediaType > ;
2021-08-04 14:17:53 -07:00
// Get the extension for the file for the next two statements
string extension = Env . Parameters ? . GetDefaultExtension ( mediaType ) ;
2022-12-13 11:48:26 -08:00
// Set the output filename, if it's not already
2023-09-25 21:16:43 -04:00
if ( string . IsNullOrEmpty ( this . Parent . OutputPathTextBox . Text ) )
2022-12-13 11:48:26 -08:00
{
string label = drive ? . FormattedVolumeLabel ? ? systemType . LongName ( ) ;
2023-09-25 21:29:55 -04:00
string directory = this . Options . DefaultOutputPath ;
2022-12-13 11:48:26 -08:00
string filename = $"{label}{extension ?? " . bin "}" ;
2021-08-04 14:17:53 -07:00
2023-02-23 12:31:27 -05:00
// If the path ends with the label already
if ( directory . EndsWith ( label , StringComparison . OrdinalIgnoreCase ) )
directory = Path . GetDirectoryName ( directory ) ;
2023-09-25 21:16:43 -04:00
this . Parent . OutputPathTextBox . Text = Path . Combine ( directory , label , filename ) ;
2022-12-13 11:48:26 -08:00
}
2021-08-04 14:17:53 -07:00
2022-12-13 11:48:26 -08:00
// Set the output filename, if we changed drives
else if ( driveChanged )
{
string label = drive ? . FormattedVolumeLabel ? ? systemType . LongName ( ) ;
2023-09-26 21:09:53 -04:00
string oldPath = InfoTool . NormalizeOutputPaths ( this . Parent . OutputPathTextBox . Text , false ) ;
string oldFilename = Path . GetFileNameWithoutExtension ( oldPath ) ;
string directory = Path . GetDirectoryName ( oldPath ) ;
2022-12-13 11:48:26 -08:00
string filename = $"{label}{extension ?? " . bin "}" ;
2021-08-04 14:17:53 -07:00
2023-02-23 12:31:27 -05:00
// If the previous path included the label
if ( directory . EndsWith ( oldFilename , StringComparison . OrdinalIgnoreCase ) )
directory = Path . GetDirectoryName ( directory ) ;
// If the path ends with the label already
if ( directory . EndsWith ( label , StringComparison . OrdinalIgnoreCase ) )
directory = Path . GetDirectoryName ( directory ) ;
2023-09-25 21:16:43 -04:00
this . Parent . OutputPathTextBox . Text = Path . Combine ( directory , label , filename ) ;
2022-12-13 11:48:26 -08:00
}
2021-08-04 14:17:53 -07:00
2023-08-28 11:24:58 -04:00
// Otherwise, reset the extension of the currently set path
else
{
2023-09-26 21:09:53 -04:00
string oldPath = InfoTool . NormalizeOutputPaths ( this . Parent . OutputPathTextBox . Text , false ) ;
string filename = Path . GetFileNameWithoutExtension ( oldPath ) ;
string directory = Path . GetDirectoryName ( oldPath ) ;
2023-08-28 11:24:58 -04:00
filename = $"{filename}{extension ?? " . bin "}" ;
2023-09-25 21:16:43 -04:00
this . Parent . OutputPathTextBox . Text = Path . Combine ( directory , filename ) ;
2023-08-28 11:24:58 -04:00
}
2021-08-04 14:17:53 -07:00
// Ensure the UI gets updated
2023-09-25 21:16:43 -04:00
this . Parent . UpdateLayout ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Process the current custom parameters back into UI values
/// </summary>
2023-09-25 21:16:43 -04:00
public void ProcessCustomParameters ( )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
Env . SetParameters ( this . Parent . ParametersTextBox . Text ) ;
2021-08-04 14:17:53 -07:00
if ( Env . Parameters = = null )
return ;
2022-01-13 10:25:57 -08:00
// Catch this in case there's an input path issue
try
{
int driveIndex = Drives . Select ( d = > d . Letter ) . ToList ( ) . IndexOf ( Env . Parameters . InputPath [ 0 ] ) ;
if ( driveIndex > - 1 )
2023-09-25 21:16:43 -04:00
this . Parent . DriveLetterComboBox . SelectedIndex = driveIndex ;
2022-01-13 10:25:57 -08:00
}
catch { }
2022-03-02 00:43:05 -05:00
2021-08-04 14:17:53 -07:00
int driveSpeed = Env . Parameters . Speed ? ? - 1 ;
if ( driveSpeed > 0 )
2023-09-25 21:16:43 -04:00
this . Parent . DriveSpeedComboBox . SelectedValue = driveSpeed ;
2021-08-04 14:17:53 -07:00
else
2023-09-25 21:16:43 -04:00
Env . Parameters . Speed = this . Parent . DriveSpeedComboBox . SelectedValue as int? ;
2021-08-04 14:17:53 -07:00
2023-07-19 12:51:22 -04:00
// Disable change handling
DisableEventHandlers ( ) ;
2023-09-26 21:09:53 -04:00
this . Parent . OutputPathTextBox . Text = InfoTool . NormalizeOutputPaths ( Env . Parameters . OutputPath , true ) ;
2021-08-04 14:17:53 -07:00
MediaType ? mediaType = Env . Parameters . GetMediaType ( ) ;
int mediaTypeIndex = MediaTypes . FindIndex ( m = > m = = mediaType ) ;
if ( mediaTypeIndex > - 1 )
2023-09-25 21:16:43 -04:00
this . Parent . MediaTypeComboBox . SelectedIndex = mediaTypeIndex ;
2023-07-19 12:51:22 -04:00
// Reenable change handling
EnableEventHandlers ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Scan and show copy protection for the current disc
/// </summary>
2023-09-25 21:29:55 -04:00
public async void ScanAndShowProtection ( )
2021-08-04 14:17:53 -07:00
{
// Determine current environment, just in case
if ( Env = = null )
2023-09-25 21:29:55 -04:00
Env = DetermineEnvironment ( ) ;
2021-08-04 14:17:53 -07:00
// Pull the drive letter from the UI directly, just in case
2023-09-25 21:16:43 -04:00
var drive = this . Parent . DriveLetterComboBox . SelectedItem as Drive ;
2021-08-04 14:17:53 -07:00
if ( drive . Letter ! = default ( char ) )
{
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Scanning for copy protection in {drive.Letter}" ) ;
2021-08-04 14:17:53 -07:00
2023-09-25 21:16:43 -04:00
var tempContent = this . Parent . StatusLabel . Text ;
this . Parent . StatusLabel . Text = "Scanning for copy protection... this might take a while!" ;
this . Parent . StartStopButton . IsEnabled = false ;
this . Parent . MediaScanButton . IsEnabled = false ;
this . Parent . UpdateVolumeLabel . IsEnabled = false ;
this . Parent . CopyProtectScanButton . IsEnabled = false ;
2021-08-04 14:17:53 -07:00
var progress = new Progress < ProtectionProgress > ( ) ;
progress . ProgressChanged + = ProgressUpdated ;
2023-09-25 21:29:55 -04:00
( var protections , string error ) = await Protection . RunProtectionScanOnPath ( drive . Letter + ":\\" , this . Options , progress ) ;
2022-04-04 22:06:56 -07:00
string output = Protection . FormatProtections ( protections ) ;
2021-08-04 14:17:53 -07:00
2023-04-17 14:06:27 -04:00
// If SmartE is detected on the current disc, remove `/sf` from the flags for DIC only -- Disabled until further notice
//if (Env.InternalProgram == InternalProgram.DiscImageCreator && output.Contains("SmartE"))
//{
// ((Modules.DiscImageCreator.Parameters)Env.Parameters)[Modules.DiscImageCreator.FlagStrings.ScanFileProtect] = false;
2023-09-25 21:29:55 -04:00
// if (this.Options.VerboseLogging)
2023-09-25 21:21:51 -04:00
// this.Logger.VerboseLogLn($"SmartE detected, removing {Modules.DiscImageCreator.FlagStrings.ScanFileProtect} from parameters");
2023-04-17 14:06:27 -04:00
//}
2021-08-04 14:17:53 -07:00
2023-09-25 21:16:43 -04:00
if ( ! this . Parent . LogPanel . IsExpanded )
2021-08-04 14:17:53 -07:00
{
2022-04-04 22:06:56 -07:00
if ( string . IsNullOrEmpty ( error ) )
2021-08-04 14:17:53 -07:00
CustomMessageBox . Show ( output , "Detected Protection(s)" , MessageBoxButton . OK , MessageBoxImage . Information ) ;
else
CustomMessageBox . Show ( "An exception occurred, see the log for details" , "Error!" , MessageBoxButton . OK , MessageBoxImage . Error ) ;
}
2022-04-04 22:06:56 -07:00
if ( string . IsNullOrEmpty ( error ) )
2023-09-25 21:21:51 -04:00
this . Logger . LogLn ( $"Detected the following protections in {drive.Letter}:\r\n\r\n{output}" ) ;
2021-08-04 14:17:53 -07:00
else
2023-09-25 21:21:51 -04:00
this . Logger . ErrorLogLn ( $"Path could not be scanned! Exception information:\r\n\r\n{error}" ) ;
2021-08-04 14:17:53 -07:00
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = tempContent ;
this . Parent . StartStopButton . IsEnabled = ShouldEnableDumpingButton ( ) ;
this . Parent . MediaScanButton . IsEnabled = true ;
this . Parent . UpdateVolumeLabel . IsEnabled = true ;
this . Parent . CopyProtectScanButton . IsEnabled = true ;
2021-08-04 14:17:53 -07:00
}
}
/// <summary>
/// Set the current disc type in the combo box
/// </summary>
2023-09-25 21:16:43 -04:00
private void SetCurrentDiscType ( )
2021-08-04 14:17:53 -07:00
{
// 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 )
2023-09-25 21:16:43 -04:00
this . Parent . MediaTypeComboBox . SelectedIndex = index ;
2021-08-04 14:17:53 -07:00
else
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = $"Disc of type '{CurrentMediaType.LongName()}' found, but the current system does not support it!" ;
2021-08-04 14:17:53 -07:00
// Ensure the UI gets updated
2023-09-25 21:16:43 -04:00
this . Parent . UpdateLayout ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Set the drive speed based on reported maximum and user-defined option
/// </summary>
2023-09-25 21:29:55 -04:00
public void SetSupportedDriveSpeed ( )
2021-08-04 14:17:53 -07:00
{
// Set the drive speed list that's appropriate
var values = Interface . GetSpeedsForMediaType ( CurrentMediaType ) ;
2023-09-25 21:16:43 -04:00
this . Parent . DriveSpeedComboBox . ItemsSource = values ;
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Supported media speeds: {string.Join(" , ", values)}" ) ;
2021-08-04 14:17:53 -07:00
// Set the selected speed
int speed ;
switch ( CurrentMediaType )
{
case MediaType . CDROM :
case MediaType . GDROM :
2023-09-25 21:29:55 -04:00
speed = this . Options . PreferredDumpSpeedCD ;
2021-08-04 14:17:53 -07:00
break ;
case MediaType . DVD :
case MediaType . NintendoGameCubeGameDisc :
case MediaType . NintendoWiiOpticalDisc :
2023-09-25 21:29:55 -04:00
speed = this . Options . PreferredDumpSpeedDVD ;
2021-08-04 14:17:53 -07:00
break ;
2022-12-02 14:39:17 -08:00
case MediaType . HDDVD :
2023-09-25 21:29:55 -04:00
speed = this . Options . PreferredDumpSpeedHDDVD ;
2022-12-02 14:39:17 -08:00
break ;
2021-08-04 14:17:53 -07:00
case MediaType . BluRay :
2023-09-25 21:29:55 -04:00
speed = this . Options . PreferredDumpSpeedBD ;
2021-08-04 14:17:53 -07:00
break ;
default :
2023-09-25 21:29:55 -04:00
speed = this . Options . PreferredDumpSpeedCD ;
2021-08-04 14:17:53 -07:00
break ;
}
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( $"Setting drive speed to: {speed}" ) ;
2023-09-25 21:16:43 -04:00
this . Parent . DriveSpeedComboBox . SelectedValue = speed ;
2021-08-04 14:17:53 -07:00
// Ensure the UI gets updated
2023-09-25 21:16:43 -04:00
this . Parent . UpdateLayout ( ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Determine if the dumping button should be enabled
/// </summary>
2023-09-25 21:16:43 -04:00
private bool ShouldEnableDumpingButton ( )
2021-08-04 14:17:53 -07:00
{
2023-02-23 16:55:27 -05:00
return Drives ! = null
2021-08-04 14:17:53 -07:00
& & Drives . Count > 0
2023-09-25 21:16:43 -04:00
& & this . Parent . SystemTypeComboBox . SelectedIndex > - 1
& & this . Parent . SystemTypeComboBox . SelectedItem as RedumpSystemComboBoxItem ! = null
& & ! string . IsNullOrEmpty ( this . Parent . ParametersTextBox . Text ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Show the disc information window
/// </summary>
/// <param name="submissionInfo">SubmissionInfo object to display and possibly change</param>
/// <returns>Dialog open result</returns>
private ( bool? , SubmissionInfo ) ShowDiscInformationWindow ( SubmissionInfo submissionInfo )
{
2023-09-25 21:29:55 -04:00
if ( this . Options . ShowDiscEjectReminder )
2023-09-25 21:16:43 -04:00
CustomMessageBox . Show ( "It is now safe to eject the disc" , "Eject" , MessageBoxButton . OK , MessageBoxImage . Information ) ;
2021-08-04 14:17:53 -07:00
2023-09-25 21:29:55 -04:00
var discInformationWindow = new DiscInformationWindow ( this . Options , submissionInfo )
2021-08-04 14:17:53 -07:00
{
2023-09-25 21:16:43 -04:00
Owner = this . Parent ,
2023-09-26 21:39:41 -04:00
Topmost = true ,
2021-08-04 14:17:53 -07:00
WindowStartupLocation = WindowStartupLocation . CenterOwner ,
} ;
bool? result = discInformationWindow . ShowDialog ( ) ;
// Copy back the submission info changes, if necessary
if ( result = = true )
submissionInfo = discInformationWindow . DiscInformationViewModel . SubmissionInfo . Clone ( ) as SubmissionInfo ;
return ( result , submissionInfo ) ;
}
/// <summary>
/// Begin the dumping process using the given inputs
/// </summary>
2023-09-25 21:29:55 -04:00
public async void StartDumping ( )
2021-08-04 14:17:53 -07:00
{
// One last check to determine environment, just in case
2023-09-25 21:29:55 -04:00
Env = DetermineEnvironment ( ) ;
2021-08-04 14:17:53 -07:00
2022-03-01 16:41:54 -08:00
// Force an internal drive refresh in case the user entered things manually
Env . Drive . RefreshDrive ( ) ;
2021-08-04 14:17:53 -07:00
// If still in custom parameter mode, check that users meant to continue or not
2023-09-25 21:16:43 -04:00
if ( this . Parent . EnableParametersCheckBox . IsChecked = = true )
2021-08-04 14:17:53 -07:00
{
MessageBoxResult result = CustomMessageBox . 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 )
{
2023-09-25 21:16:43 -04:00
this . Parent . EnableParametersCheckBox . IsChecked = false ;
this . Parent . ParametersTextBox . IsEnabled = false ;
ProcessCustomParameters ( ) ;
2021-08-04 14:17:53 -07:00
}
else if ( result = = MessageBoxResult . Cancel )
2023-09-25 16:58:14 -04:00
{
2021-08-04 14:17:53 -07:00
return ;
2023-09-25 16:58:14 -04:00
}
2021-08-04 14:17:53 -07:00
// If "No", then we continue with the current known environment
}
2023-04-13 12:33:14 -04:00
// Run path adjustments for DiscImageCreator -- Disabled until further notice
//Env.AdjustPathsForDiscImageCreator();
2022-02-13 22:49:33 -08:00
2021-08-04 14:17:53 -07:00
try
{
2022-03-05 21:50:18 -08:00
// Run pre-dumping validation checks
2023-09-25 21:21:51 -04:00
if ( ! ValidateBeforeDumping ( ) )
2022-03-05 21:50:18 -08:00
return ;
2021-08-04 14:17:53 -07:00
// Disable all UI elements apart from dumping button
2023-09-25 21:16:43 -04:00
DisableAllUIElements ( ) ;
2021-08-04 14:17:53 -07:00
2022-12-13 11:48:26 -08:00
// Refresh the drive, if it wasn't null
2023-09-25 21:39:28 -04:00
Env . Drive ? . RefreshDrive ( ) ;
2022-12-13 11:48:26 -08:00
2021-08-04 14:17:53 -07:00
// Output to the label and log
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = "Starting dumping process... Please wait!" ;
2023-09-25 21:21:51 -04:00
this . Logger . LogLn ( "Starting dumping process... Please wait!" ) ;
2023-09-25 21:29:55 -04:00
if ( this . Options . ToolsInSeparateWindow )
2023-09-25 21:21:51 -04:00
this . Logger . LogLn ( "Look for the separate command window for more details" ) ;
2021-08-04 14:17:53 -07:00
else
2023-09-25 21:21:51 -04:00
this . Logger . LogLn ( "Program outputs may be slow to populate in the log window" ) ;
2021-08-04 14:17:53 -07:00
// Get progress indicators
var resultProgress = new Progress < Result > ( ) ;
resultProgress . ProgressChanged + = ProgressUpdated ;
var protectionProgress = new Progress < ProtectionProgress > ( ) ;
protectionProgress . ProgressChanged + = ProgressUpdated ;
Env . ReportStatus + = ProgressUpdated ;
// Run the program with the parameters
Result result = await Env . Run ( resultProgress ) ;
2023-09-25 21:21:51 -04:00
this . Logger . ResetProgressBar ( ) ;
2021-08-04 14:17:53 -07:00
// If we didn't execute a dumping command we cannot get submission output
if ( ! Env . Parameters . IsDumpingCommand ( ) )
{
2023-09-25 21:21:51 -04:00
this . Logger . LogLn ( "No dumping command was run, submission information will not be gathered." ) ;
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = "Execution complete!" ;
2021-08-04 14:17:53 -07:00
// Reset all UI elements
2023-09-25 21:16:43 -04:00
EnableAllUIElements ( ) ;
2021-08-04 14:17:53 -07:00
return ;
}
// Verify dump output and save it
if ( result )
{
result = await Env . VerifyAndSaveDumpOutput ( resultProgress , protectionProgress , ShowDiscInformationWindow ) ;
}
else
{
2023-09-25 21:21:51 -04:00
this . Logger . ErrorLogLn ( result . Message ) ;
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = "Execution failed!" ;
2021-08-04 14:17:53 -07:00
}
}
catch ( Exception ex )
{
2023-09-25 21:21:51 -04:00
this . Logger . ErrorLogLn ( ex . ToString ( ) ) ;
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = "An exception occurred!" ;
2021-08-04 14:17:53 -07:00
}
finally
{
// Reset all UI elements
2023-09-25 21:16:43 -04:00
EnableAllUIElements ( ) ;
2021-08-04 14:17:53 -07:00
}
}
2022-03-05 21:50:18 -08:00
/// <summary>
/// Perform validation, including user input, before attempting to start dumping
/// </summary>
/// <returns>True if dumping should start, false otherwise</returns>
2023-09-25 21:21:51 -04:00
private bool ValidateBeforeDumping ( )
2022-03-05 21:50:18 -08:00
{
2022-12-13 11:48:26 -08:00
// Validate that we have an output path of any sort
if ( string . IsNullOrWhiteSpace ( Env . OutputPath ) )
{
2023-09-25 21:39:28 -04:00
_ = CustomMessageBox . Show ( "No output path was provided so dumping cannot continue." , "Missing Path" , MessageBoxButton . OK , MessageBoxImage . Exclamation ) ;
2023-09-25 21:21:51 -04:00
this . Logger . LogLn ( "Dumping aborted!" ) ;
2022-12-13 11:48:26 -08:00
return false ;
}
2022-03-05 21:50:18 -08:00
// Validate that the user explicitly wants an inactive drive to be considered for dumping
if ( ! Env . Drive . MarkedActive )
{
string message = "The currently selected drive does not appear to contain a disc! "
+ ( ! Env . System . DetectedByWindows ( ) ? $"This is normal for {Env.System.LongName()} as the discs may not be readable on Windows. " : string . Empty )
+ "Do you want to continue?" ;
MessageBoxResult mbresult = CustomMessageBox . Show ( message , "No Disc Detected" , MessageBoxButton . YesNo , MessageBoxImage . Exclamation ) ;
if ( mbresult = = MessageBoxResult . No | | mbresult = = MessageBoxResult . Cancel | | mbresult = = MessageBoxResult . None )
{
2023-09-25 21:21:51 -04:00
this . Logger . LogLn ( "Dumping aborted!" ) ;
2022-03-05 21:50:18 -08:00
return false ;
}
}
2022-12-13 11:48:26 -08:00
// Pre-split the output path
string outputDirectory = Path . GetDirectoryName ( Env . OutputPath ) ;
string outputFilename = Path . GetFileName ( Env . OutputPath ) ;
2022-03-05 21:50:18 -08:00
// If a complete dump already exists
2022-12-13 11:48:26 -08:00
( bool foundFiles , List < string > _ ) = InfoTool . FoundAllFiles ( outputDirectory , outputFilename , Env . Parameters , true ) ;
2022-03-05 21:50:18 -08:00
if ( foundFiles )
{
MessageBoxResult mbresult = CustomMessageBox . 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 )
{
2023-09-25 21:21:51 -04:00
this . Logger . LogLn ( "Dumping aborted!" ) ;
2022-03-05 21:50:18 -08:00
return false ;
}
}
// Validate that at least some space exists
// TODO: Tie this to the size of the disc, type of disc, etc.
2022-12-13 11:48:26 -08:00
string fullPath = Path . GetFullPath ( outputDirectory ) ;
2022-03-05 21:50:18 -08:00
var driveInfo = new DriveInfo ( Path . GetPathRoot ( fullPath ) ) ;
if ( driveInfo . AvailableFreeSpace < Math . Pow ( 2 , 30 ) )
{
MessageBoxResult mbresult = CustomMessageBox . Show ( "There is less than 1gb of space left on the target drive. Are you sure you want to continue?" , "Low Space" , MessageBoxButton . YesNo , MessageBoxImage . Exclamation ) ;
if ( mbresult = = MessageBoxResult . No | | mbresult = = MessageBoxResult . Cancel | | mbresult = = MessageBoxResult . None )
{
2023-09-25 21:21:51 -04:00
this . Logger . LogLn ( "Dumping aborted!" ) ;
2022-03-05 21:50:18 -08:00
return false ;
}
}
// If nothing above fails, we want to continue
return true ;
}
2023-07-17 13:23:00 -04:00
#endregion
2021-08-04 14:17:53 -07:00
#region Event Handlers
/// <summary>
/// Handler for OptionsWindow OnUpdated event
/// </summary>
private void OnOptionsUpdated ( object sender , EventArgs e ) = >
2023-09-25 21:29:55 -04:00
UpdateOptions ( sender as OptionsWindow ) ;
2021-08-04 14:17:53 -07:00
#region Progress Reporting
/// <summary>
/// Handler for Result ProgressChanged event
/// </summary>
private void ProgressUpdated ( object sender , string value )
{
try
{
value = value ? ? string . Empty ;
2023-09-25 21:21:51 -04:00
this . Logger . LogLn ( value ) ;
2021-08-04 14:17:53 -07:00
}
catch { }
}
/// <summary>
/// Handler for Result ProgressChanged event
/// </summary>
private void ProgressUpdated ( object sender , Result value )
{
string message = value ? . Message ;
// Update the label with only the first line of output
if ( message . Contains ( "\n" ) )
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = value . Message . Split ( '\n' ) [ 0 ] + " (See log output)" ;
2021-08-04 14:17:53 -07:00
else
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = value . Message ;
2021-08-04 14:17:53 -07:00
// Log based on success or failure
2023-09-25 21:29:55 -04:00
if ( value & & this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( message ) ;
2023-09-25 15:36:50 -04:00
else if ( ! value )
2023-09-25 21:21:51 -04:00
this . Logger . ErrorLogLn ( message ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Handler for ProtectionProgress ProgressChanged event
/// </summary>
private void ProgressUpdated ( object sender , ProtectionProgress value )
{
string message = $"{value.Percentage * 100:N2}%: {value.Filename} - {value.Protection}" ;
2023-09-25 21:16:43 -04:00
this . Parent . StatusLabel . Text = message ;
2023-09-25 21:29:55 -04:00
if ( this . Options . VerboseLogging )
2023-09-25 21:21:51 -04:00
this . Logger . VerboseLogLn ( message ) ;
2021-08-04 14:17:53 -07:00
}
#endregion
#region Menu Bar
/// <summary>
/// Handler for AboutMenuItem Click event
/// </summary>
private void AboutClick ( object sender , RoutedEventArgs e ) = >
2023-09-25 21:21:51 -04:00
ShowAboutText ( ) ;
2021-08-04 14:17:53 -07:00
/// <summary>
/// Handler for AppExitMenuItem Click event
/// </summary>
private void AppExitClick ( object sender , RoutedEventArgs e ) = >
ExitApplication ( ) ;
/// <summary>
/// Handler for CheckForUpdatesMenuItem Click event
/// </summary>
private void CheckForUpdatesClick ( object sender , RoutedEventArgs e ) = >
2023-09-25 21:21:51 -04:00
CheckForUpdates ( showIfSame : true ) ;
2021-08-04 14:17:53 -07:00
2022-01-07 13:25:46 -08:00
/// <summary>
/// Handler for DebugViewMenuItem Click event
/// </summary>
private void DebugViewClick ( object sender , RoutedEventArgs e ) = >
ShowDebugDiscInfoWindow ( ) ;
2021-08-04 14:17:53 -07:00
/// <summary>
/// Handler for OptionsMenuItem Click event
/// </summary>
private void OptionsMenuItemClick ( object sender , RoutedEventArgs e ) = >
2023-09-25 21:29:55 -04:00
ShowOptionsWindow ( ) ;
2021-08-04 14:17:53 -07:00
#endregion
#region User Area
/// <summary>
/// Handler for CopyProtectScanButton Click event
/// </summary>
private void CopyProtectScanButtonClick ( object sender , RoutedEventArgs e ) = >
2023-09-25 21:29:55 -04:00
ScanAndShowProtection ( ) ;
2021-08-04 14:17:53 -07:00
/// <summary>
/// Handler for DriveLetterComboBox SelectionChanged event
/// </summary>
private void DriveLetterComboBoxSelectionChanged ( object sender , SelectionChangedEventArgs e )
{
if ( _canExecuteSelectionChanged )
2023-09-25 21:29:55 -04:00
InitializeUIValues ( removeEventHandlers : true , rescanDrives : false ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
/// Handler for DriveSpeedComboBox SelectionChanged event
/// </summary>
private void DriveSpeedComboBoxSelectionChanged ( object sender , SelectionChangedEventArgs e )
{
if ( _canExecuteSelectionChanged )
2023-09-25 21:29:55 -04:00
EnsureDiscInformation ( ) ;
2021-08-04 14:17:53 -07:00
}
2023-04-11 11:15:53 -04:00
/// <summary>
/// Handler for DumpingProgramComboBox SelectionChanged event
/// </summary>
private void DumpingProgramComboBoxSelectionChanged ( object sender , SelectionChangedEventArgs e )
{
if ( _canExecuteSelectionChanged )
2023-09-25 21:29:55 -04:00
ChangeDumpingProgram ( ) ;
2023-04-11 11:15:53 -04:00
}
2021-08-04 14:17:53 -07:00
/// <summary>
/// Handler for EnableParametersCheckBox Click event
/// </summary>
private void EnableParametersCheckBoxClick ( object sender , RoutedEventArgs e ) = >
2023-09-25 21:16:43 -04:00
ToggleParameters ( ) ;
2021-08-04 14:17:53 -07:00
/// <summary>
/// Handler for MediaScanButton Click event
/// </summary>
private void MediaScanButtonClick ( object sender , RoutedEventArgs e ) = >
2023-09-25 21:29:55 -04:00
InitializeUIValues ( removeEventHandlers : true , rescanDrives : true ) ;
2021-08-04 14:17:53 -07:00
/// <summary>
/// Handler for MediaTypeComboBox SelectionChanged event
/// </summary>
private void MediaTypeComboBoxSelectionChanged ( object sender , SelectionChangedEventArgs e )
{
if ( _canExecuteSelectionChanged )
2023-09-25 21:29:55 -04:00
ChangeMediaType ( e ) ;
2021-08-04 14:17:53 -07:00
}
/// <summary>
2022-12-13 11:48:26 -08:00
/// Handler for OutputPathBrowseButton Click event
2021-08-04 14:17:53 -07:00
/// </summary>
2022-12-13 11:48:26 -08:00
private void OutputPathBrowseButtonClick ( object sender , RoutedEventArgs e ) = >
2023-09-25 21:29:55 -04:00
SetOutputPath ( ) ;
2021-08-04 14:17:53 -07:00
2022-12-30 10:59:32 -08:00
/// <summary>
/// Handler for OutputPathTextBox TextChanged event
/// </summary>
private void OutputPathTextBoxTextChanged ( object sender , TextChangedEventArgs e )
2023-07-19 12:51:22 -04:00
{
if ( _canExecuteSelectionChanged )
2023-09-25 21:29:55 -04:00
EnsureDiscInformation ( ) ;
2023-07-19 12:51:22 -04:00
}
2022-12-30 10:59:32 -08:00
2021-08-04 14:17:53 -07:00
/// <summary>
/// Handler for StartStopButton Click event
/// </summary>
private void StartStopButtonClick ( object sender , RoutedEventArgs e ) = >
2023-09-25 21:29:55 -04:00
ToggleStartStop ( ) ;
2021-08-04 14:17:53 -07:00
/// <summary>
/// Handler for SystemTypeComboBox SelectionChanged event
/// </summary>
2022-03-06 00:04:23 -08:00
private void SystemTypeComboBoxSelectionChanged ( object sender , SelectionChangedEventArgs e )
2021-08-04 14:17:53 -07:00
{
if ( _canExecuteSelectionChanged )
2023-09-25 21:29:55 -04:00
ChangeSystem ( ) ;
2021-08-04 14:17:53 -07:00
}
2022-03-06 00:04:23 -08:00
/// <summary>
/// Handler for UpdateVolumeLabel Click event
/// </summary>
private void UpdateVolumeLabelClick ( object sender , RoutedEventArgs e )
{
if ( _canExecuteSelectionChanged )
2023-03-04 22:40:10 -05:00
{
2023-09-25 21:29:55 -04:00
if ( this . Options . FastUpdateLabel )
FastUpdateLabel ( removeEventHandlers : true ) ;
2023-03-04 22:40:10 -05:00
else
2023-09-25 21:29:55 -04:00
InitializeUIValues ( removeEventHandlers : true , rescanDrives : false ) ;
2023-03-04 22:40:10 -05:00
}
2022-03-06 00:04:23 -08:00
}
2021-08-04 14:17:53 -07:00
#endregion
#endregion // Event Handlers
}
}