Files
MPF/MPF.UI/Windows/MainWindow.xaml.cs

880 lines
36 KiB
C#
Raw Permalink Normal View History

2018-06-14 20:40:41 -04:00
using System;
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
2023-10-08 23:46:24 -04:00
using System.IO;
#if NET40
using System.Threading.Tasks;
#endif
2023-10-08 20:52:29 -04:00
using System.Windows;
using System.Windows.Controls;
using MPF.Frontend;
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
using MPF.Frontend.Tools;
2024-05-23 15:40:12 -04:00
using MPF.Frontend.ViewModels;
using MPF.UI.Themes;
2023-11-16 12:45:47 -05:00
using SabreTools.RedumpLib;
2023-10-08 23:15:24 -04:00
using SabreTools.RedumpLib.Data;
using WPFCustomMessageBox;
2023-10-08 23:46:24 -04:00
using WinForms = System.Windows.Forms;
2024-05-23 21:35:02 -04:00
namespace MPF.UI.Windows
2018-05-12 19:48:18 -04:00
{
public partial class MainWindow : WindowBase
2018-05-12 19:48:18 -04:00
{
/// <summary>
/// Read-only access to the current main view model
/// </summary>
2023-10-11 11:49:56 -04:00
public MainViewModel MainViewModel => DataContext as MainViewModel ?? new MainViewModel();
2023-11-30 23:34:44 -05:00
#if NET35
#region Top Menu Bar
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
// Buttons
private MenuItem? AboutMenuItem => ItemHelper.FindChild<MenuItem>(this, "AboutMenuItem");
private MenuItem? AppExitMenuItem => ItemHelper.FindChild<MenuItem>(this, "AppExitMenuItem");
private MenuItem? CheckForUpdatesMenuItem => ItemHelper.FindChild<MenuItem>(this, "CheckForUpdatesMenuItem");
private MenuItem? DebugViewMenuItem => ItemHelper.FindChild<MenuItem>(this, "DebugViewMenuItem");
private MenuItem? CheckDumpMenuItem => ItemHelper.FindChild<MenuItem>(this, "CheckDumpMenuItem");
private MenuItem? CreateIRDMenuItem => ItemHelper.FindChild<MenuItem>(this, "CreateIRDMenuItem");
private MenuItem? OptionsMenuItem => ItemHelper.FindChild<MenuItem>(this, "OptionsMenuItem");
2023-11-30 23:34:44 -05:00
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
// Languages
private MenuItem? EnglishMenuItem => ItemHelper.FindChild<MenuItem>(this, "EnglishMenuItem");
2025-10-17 17:35:27 -04:00
private MenuItem? FrenchMenuItem => ItemHelper.FindChild<MenuItem>(this, "FrenchMenuItem");
private MenuItem? GermanMenuItem => ItemHelper.FindChild<MenuItem>(this, "GermanMenuItem");
private MenuItem? ItalianMenuItem => ItemHelper.FindChild<MenuItem>(this, "ItalianMenuItem");
private MenuItem? JapaneseMenuItem => ItemHelper.FindChild<MenuItem>(this, "JapaneseMenuItem");
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
private MenuItem? KoreanMenuItem => ItemHelper.FindChild<MenuItem>(this, "KoreanMenuItem");
2025-10-17 17:35:27 -04:00
private MenuItem? PolishMenuItem => ItemHelper.FindChild<MenuItem>(this, "PolishMenuItem");
private MenuItem? RussianMenuItem => ItemHelper.FindChild<MenuItem>(this, "RussianMenuItem");
private MenuItem? SpanishMenuItem => ItemHelper.FindChild<MenuItem>(this, "SpanishMenuItem");
private MenuItem? SwedishMenuItem => ItemHelper.FindChild<MenuItem>(this, "SwedishMenuItem");
2025-10-18 18:10:45 -04:00
private MenuItem? UkrainianMenuItem => ItemHelper.FindChild<MenuItem>(this, "UkrainianMenuItem");
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
2023-11-30 23:34:44 -05:00
#endregion
#region Settings
private ComboBox? DriveLetterComboBox => ItemHelper.FindChild<ComboBox>(this, "DriveLetterComboBox");
private ComboBox? DriveSpeedComboBox => ItemHelper.FindChild<ComboBox>(this, "DriveSpeedComboBox");
private ComboBox? DumpingProgramComboBox => ItemHelper.FindChild<ComboBox>(this, "DumpingProgramComboBox");
private CheckBox? EnableParametersCheckBox => ItemHelper.FindChild<CheckBox>(this, "EnableParametersCheckBox");
private ComboBox? MediaTypeComboBox => ItemHelper.FindChild<ComboBox>(this, "MediaTypeComboBox");
private Button? OutputPathBrowseButton => ItemHelper.FindChild<Button>(this, "OutputPathBrowseButton");
private TextBox? OutputPathTextBox => ItemHelper.FindChild<TextBox>(this, "OutputPathTextBox");
private Label? SystemMediaTypeLabel => ItemHelper.FindChild<Label>(this, "SystemMediaTypeLabel");
private ComboBox? SystemTypeComboBox => ItemHelper.FindChild<ComboBox>(this, "SystemTypeComboBox");
2023-11-30 23:34:44 -05:00
#endregion
#region Controls
private Button? CopyProtectScanButton => ItemHelper.FindChild<Button>(this, "CopyProtectScanButton");
private Button? MediaScanButton => ItemHelper.FindChild<Button>(this, "MediaScanButton");
private Button? StartStopButton => ItemHelper.FindChild<Button>(this, "StartStopButton");
private Button? UpdateVolumeLabel => ItemHelper.FindChild<Button>(this, "UpdateVolumeLabel");
2023-11-30 23:34:44 -05:00
#endregion
#region Status
private LogOutput? LogOutput => ItemHelper.FindChild<LogOutput>(this, "LogOutput");
2023-11-30 23:34:44 -05:00
#endregion
#endif
/// <summary>
/// Constructor
/// </summary>
2023-11-15 12:10:54 -05:00
public MainWindow()
{
2023-11-30 23:34:44 -05:00
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
this.Closing += MainWindowClosing;
2023-11-30 23:34:44 -05:00
#endif
#if NET452_OR_GREATER || NETCOREAPP
2023-11-15 12:10:54 -05:00
var chrome = new System.Windows.Shell.WindowChrome
{
CaptionHeight = 0,
ResizeBorderThickness = new Thickness(0),
};
System.Windows.Shell.WindowChrome.SetWindowChrome(this, chrome);
#endif
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
// Set all resources before window loads (Must set English here)
SetInterfaceLanguage(InterfaceLanguage.English);
2023-11-15 12:10:54 -05:00
}
2020-09-10 23:21:18 -07:00
/// <summary>
/// Handler for MainWindow OnContentRendered event
/// </summary>
protected override void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
2023-10-08 20:52:29 -04:00
// Disable buttons until we load fully
2023-10-08 22:49:46 -04:00
MainViewModel.StartStopButtonEnabled = false;
MainViewModel.MediaScanButtonEnabled = false;
MainViewModel.UpdateVolumeLabelEnabled = false;
MainViewModel.CopyProtectScanButtonEnabled = false;
2023-10-08 20:52:29 -04:00
// Add the click handlers to the UI
AddEventHandlers();
// Display the debug option in the menu, if necessary
if (MainViewModel.Options.ShowDebugViewMenuItem)
DebugViewMenuItem!.Visibility = Visibility.Visible;
2023-10-08 20:52:29 -04:00
2025-06-17 16:35:03 -04:00
MainViewModel.Init(LogOutput!.EnqueueLog, DisplayUserMessage, ShowMediaInformationWindow);
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
// Pass translation strings to MainViewModel
2025-11-11 15:52:26 -05:00
var translationStrings = new Dictionary<string, string>
{
["StartDumpingButtonString"] = (string)Application.Current.FindResource("StartDumpingButtonString"),
["StopDumpingButtonString"] = (string)Application.Current.FindResource("StopDumpingButtonString")
};
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
MainViewModel.TranslateStrings(translationStrings);
// Set interface language according to the options
SetInterfaceLanguage(MainViewModel.Options.DefaultInterfaceLanguage);
2023-10-09 11:35:49 -04:00
// Set the UI color scheme according to the options
2023-10-18 10:21:40 -04:00
ApplyTheme();
2023-10-09 11:35:49 -04:00
// Hide or show the media type box based on program
SetMediaTypeVisibility();
// Check for updates, if necessary
if (MainViewModel.Options.CheckForUpdatesOnStartup)
CheckForUpdates(showIfSame: false);
2023-10-18 01:59:55 -04:00
// Handle first-run, if necessary
if (MainViewModel.Options.FirstRun)
{
// Show the options window
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
ShowOptionsWindow((string)Application.Current.FindResource("OptionsFirstRunTitleString"));
2023-10-18 01:59:55 -04:00
}
More and more cleanup (#86) * Namespace cleanups * Make dump validation instanced * Add note to Tasks * Move stuff to DumpEnvironment Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately. * Gut Tasks * One less thing in MainWindow * Remove explicit cast * Wrong check * Create helper method * Disable scan button on dump * Remove unnecessary getters/setters * Method name/description cleanup * Address TODO * Namespace cleanups * Make dump validation instanced * Add note to Tasks * Move stuff to DumpEnvironment Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately. * Gut Tasks * One less thing in MainWindow * Remove explicit cast * Wrong check * Create helper method * Disable scan button on dump * Remove unnecessary getters/setters * Method name/description cleanup * Address TODO * Clean up OnContentRendered * Namespace cleanups * Make dump validation instanced * Add note to Tasks * Move stuff to DumpEnvironment Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately. * Gut Tasks * One less thing in MainWindow * Remove explicit cast * Wrong check * Create helper method * Disable scan button on dump * Remove unnecessary getters/setters * Method name/description cleanup * Address TODO * Clean up OnContentRendered * Update event handlers
2018-07-05 21:34:04 -07:00
}
2023-10-08 20:52:29 -04:00
#region Interface Language
2025-10-17 08:10:02 -04:00
/// <summary>
/// Set the current interface language to a provided InterfaceLanguage
/// </summary>
private void SetInterfaceLanguage(InterfaceLanguage lang)
{
// Auto detect language
if (lang == InterfaceLanguage.AutoDetect)
{
AutoSetInterfaceLanguage();
return;
}
// Set baseline language (English), required as some translations may not translate all strings
if (lang != InterfaceLanguage.English)
{
2025-11-11 15:52:26 -05:00
var baselineDictionary = new ResourceDictionary
{
Source = new Uri("../Resources/Strings.xaml", UriKind.Relative)
};
Application.Current.Resources.MergedDictionaries.Add(baselineDictionary);
}
2025-11-11 15:52:26 -05:00
var dictionary = new ResourceDictionary
{
2026-01-25 18:09:00 -05:00
#pragma warning disable IDE0072
2025-11-11 15:52:26 -05:00
Source = lang switch
{
InterfaceLanguage.English => new Uri("../Resources/Strings.xaml", UriKind.Relative),
InterfaceLanguage.French => new Uri("../Resources/Strings.fr.xaml", UriKind.Relative),
InterfaceLanguage.German => new Uri("../Resources/Strings.de.xaml", UriKind.Relative),
InterfaceLanguage.Italian => new Uri("../Resources/Strings.it.xaml", UriKind.Relative),
InterfaceLanguage.Japanese => new Uri("../Resources/Strings.ja.xaml", UriKind.Relative),
InterfaceLanguage.Korean => new Uri("../Resources/Strings.ko.xaml", UriKind.Relative),
InterfaceLanguage.Polish => new Uri("../Resources/Strings.pl.xaml", UriKind.Relative),
InterfaceLanguage.Russian => new Uri("../Resources/Strings.ru.xaml", UriKind.Relative),
InterfaceLanguage.Spanish => new Uri("../Resources/Strings.es.xaml", UriKind.Relative),
InterfaceLanguage.Swedish => new Uri("../Resources/Strings.sv.xaml", UriKind.Relative),
InterfaceLanguage.Ukrainian => new Uri("../Resources/Strings.uk.xaml", UriKind.Relative),
InterfaceLanguage.L337 => new Uri("../Resources/Strings.37.xaml", UriKind.Relative),
_ => new Uri("../Resources/Strings.xaml", UriKind.Relative),
}
2026-01-25 18:09:00 -05:00
#pragma warning restore IDE0072
};
Application.Current.Resources.MergedDictionaries.Add(dictionary);
// Update the labels in MainViewModel
2025-11-11 15:52:26 -05:00
var translationStrings = new Dictionary<string, string>
{
["StartDumpingButtonString"] = (string)Application.Current.FindResource("StartDumpingButtonString"),
["StopDumpingButtonString"] = (string)Application.Current.FindResource("StopDumpingButtonString"),
["NoSystemSelectedString"] = (string)Application.Current.FindResource("NoSystemSelectedString")
};
MainViewModel.TranslateStrings(translationStrings);
}
/// <summary>
/// Sets the interface language based on system locale
/// Should only run at app startup, use SetInterfaceLanguage(lang) elsewhere
/// </summary>
public void AutoSetInterfaceLanguage()
{
// Get current region code to distinguish regional variants of languages
2025-10-17 08:10:02 -04:00
string region = string.Empty;
try
{
// Can throw exception depending on current locale
region = new RegionInfo(CultureInfo.CurrentUICulture.Name).TwoLetterISORegionName;
}
catch { }
switch (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName)
{
2025-10-17 17:26:56 -04:00
case "en": SetInterfaceLanguage(InterfaceLanguage.English); break;
case "fr": SetInterfaceLanguage(InterfaceLanguage.French); break;
case "de": SetInterfaceLanguage(InterfaceLanguage.German); break;
case "it": SetInterfaceLanguage(InterfaceLanguage.Italian); break;
case "ja": SetInterfaceLanguage(InterfaceLanguage.Japanese); break;
case "ko": SetInterfaceLanguage(InterfaceLanguage.Korean); break;
case "pl": SetInterfaceLanguage(InterfaceLanguage.Polish); break;
case "ru": SetInterfaceLanguage(InterfaceLanguage.Russian); break;
case "es": SetInterfaceLanguage(InterfaceLanguage.Spanish); break;
case "sv": SetInterfaceLanguage(InterfaceLanguage.Swedish); break;
2025-10-18 18:10:45 -04:00
case "uk": SetInterfaceLanguage(InterfaceLanguage.Ukrainian); break;
2025-10-17 08:10:02 -04:00
// Traditional or Simplified Chinese
case "zh":
2025-10-17 08:10:02 -04:00
string[] traditionalRegions = ["TW", "HK", "MO"];
if (Array.Exists(traditionalRegions, r => r.Equals(region, StringComparison.OrdinalIgnoreCase)))
{
// TODO: Translate UI elements to Traditional Chinese
}
else
{
// TODO: Translate UI elements to Simplified Chinese
}
2026-01-25 18:09:00 -05:00
break;
2025-10-17 08:10:02 -04:00
default:
// Unsupported language, don't add any translated text
break;
}
}
#endregion
2023-10-08 20:52:29 -04:00
#region UI Functionality
/// <summary>
/// Add all event handlers
/// </summary>
public void AddEventHandlers()
{
// Menu Bar Click
AboutMenuItem!.Click += AboutClick;
AppExitMenuItem!.Click += AppExitClick;
CheckForUpdatesMenuItem!.Click += CheckForUpdatesClick;
DebugViewMenuItem!.Click += DebugViewClick;
CheckDumpMenuItem!.Click += CheckDumpMenuItemClick;
CreateIRDMenuItem!.Click += CreateIRDMenuItemClick;
OptionsMenuItem!.Click += OptionsMenuItemClick;
2025-10-17 17:35:27 -04:00
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
EnglishMenuItem!.Click += LanguageMenuItemClick;
2025-10-17 17:35:27 -04:00
FrenchMenuItem!.Click += LanguageMenuItemClick;
GermanMenuItem!.Click += LanguageMenuItemClick;
ItalianMenuItem!.Click += LanguageMenuItemClick;
JapaneseMenuItem!.Click += LanguageMenuItemClick;
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
KoreanMenuItem!.Click += LanguageMenuItemClick;
2025-10-17 17:35:27 -04:00
PolishMenuItem!.Click += LanguageMenuItemClick;
RussianMenuItem!.Click += LanguageMenuItemClick;
SpanishMenuItem!.Click += LanguageMenuItemClick;
SwedishMenuItem!.Click += LanguageMenuItemClick;
2025-10-18 18:10:45 -04:00
UkrainianMenuItem!.Click += LanguageMenuItemClick;
2023-10-08 20:52:29 -04:00
// User Area Click
CopyProtectScanButton!.Click += CopyProtectScanButtonClick;
EnableParametersCheckBox!.Click += EnableParametersCheckBoxClick;
MediaScanButton!.Click += MediaScanButtonClick;
UpdateVolumeLabel!.Click += UpdateVolumeLabelClick;
OutputPathBrowseButton!.Click += OutputPathBrowseButtonClick;
StartStopButton!.Click += StartStopButtonClick;
2023-10-08 20:52:29 -04:00
// User Area SelectionChanged
SystemTypeComboBox!.SelectionChanged += SystemTypeComboBoxSelectionChanged;
MediaTypeComboBox!.SelectionChanged += MediaTypeComboBoxSelectionChanged;
DriveLetterComboBox!.SelectionChanged += DriveLetterComboBoxSelectionChanged;
DriveSpeedComboBox!.SelectionChanged += DriveSpeedComboBoxSelectionChanged;
DumpingProgramComboBox!.SelectionChanged += DumpingProgramComboBoxSelectionChanged;
2023-10-08 20:52:29 -04:00
// User Area TextChanged
OutputPathTextBox!.TextChanged += OutputPathTextBoxTextChanged;
2023-10-08 20:52:29 -04:00
}
2023-10-08 23:46:24 -04:00
/// <summary>
/// Browse for an output file path
/// </summary>
public void BrowseFile()
{
// Get the current path, if possible
string currentPath = MainViewModel.OutputPath;
if (string.IsNullOrEmpty(currentPath) && !string.IsNullOrEmpty(MainViewModel.Options.DefaultOutputPath))
2025-11-09 20:03:46 -05:00
currentPath = Path.Combine(MainViewModel.Options.DefaultOutputPath, $"track_{DateTime.Now:yyyyMMdd-HHmm}.bin");
else if (string.IsNullOrEmpty(currentPath))
2025-11-09 20:03:46 -05:00
currentPath = $"track_{DateTime.Now:yyyyMMdd-HHmm}.bin";
if (string.IsNullOrEmpty(currentPath))
2025-11-09 20:03:46 -05:00
currentPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory!, $"track_{DateTime.Now:yyyyMMdd-HHmm}.bin");
2023-10-08 23:46:24 -04:00
// Get the full path
currentPath = Path.GetFullPath(currentPath);
// Get the directory
2023-10-11 11:49:56 -04:00
var directory = Path.GetDirectoryName(currentPath);
2023-10-08 23:46:24 -04:00
// Get the filename
string filename = Path.GetFileName(currentPath);
WinForms.FileDialog fileDialog = new WinForms.SaveFileDialog
{
FileName = filename,
InitialDirectory = directory,
};
WinForms.DialogResult result = fileDialog.ShowDialog();
if (result == WinForms.DialogResult.OK)
{
MainViewModel.OutputPath = fileDialog.FileName;
}
}
/// <summary>
/// Check for available updates
/// </summary>
/// <param name="showIfSame">True to show the box even if it's the same, false to only show if it's different</param>
public void CheckForUpdates(bool showIfSame)
{
2024-11-03 22:51:24 -05:00
MainViewModel.CheckForUpdates(out bool different, out string message, out var url);
// If we have a new version, put it in the clipboard
2025-07-23 07:51:18 -04:00
if (MainViewModel.Options.CopyUpdateUrlToClipboard && different && !string.IsNullOrEmpty(url))
{
try
{
Clipboard.SetText(url);
}
catch { }
}
if (showIfSame || different)
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
CustomMessageBox.Show(this, message, (string)Application.Current.FindResource("CheckForUpdatesTitleString"), MessageBoxButton.OK, different ? MessageBoxImage.Exclamation : MessageBoxImage.Information);
}
/// <summary>
/// Ask to confirm quitting, when an operation is running
/// </summary>
public void MainWindowClosing(object? sender, CancelEventArgs e)
{
if (MainViewModel.AskBeforeQuit)
{
MessageBoxResult result = CustomMessageBox.Show(this, (string)Application.Current.FindResource("QuitMessageString"),
(string)Application.Current.FindResource("QuitTitleString"), MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (result == MessageBoxResult.No)
e.Cancel = true;
}
}
2023-10-08 23:06:17 -04:00
/// <summary>
/// Build a dummy SubmissionInfo and display it for testing
/// </summary>
public void ShowDebugDiscInfoWindow()
{
var submissionInfo = MainViewModel.CreateDebugSubmissionInfo();
2025-06-17 16:35:03 -04:00
_ = ShowMediaInformationWindow(MainViewModel.Options, ref submissionInfo);
2024-12-03 13:20:05 -05:00
Formatter.ProcessSpecialFields(submissionInfo!);
2023-10-08 23:06:17 -04:00
}
2023-10-08 23:15:24 -04:00
/// <summary>
2025-06-17 16:35:03 -04:00
/// Show the media information window
2023-10-08 23:15:24 -04:00
/// </summary>
/// <param name="options">Options set to pass to the information window</param>
2023-10-08 23:15:24 -04:00
/// <param name="submissionInfo">SubmissionInfo object to display and possibly change</param>
/// <returns>Dialog open result</returns>
2025-06-17 16:35:03 -04:00
public bool? ShowMediaInformationWindow(Options? options, ref SubmissionInfo? submissionInfo)
2023-10-08 23:15:24 -04:00
{
if (options?.ShowDiscEjectReminder == true)
CustomMessageBox.Show(this, (string)Application.Current.FindResource("EjectMessageString"),
(string)Application.Current.FindResource("EjectTitleString"), MessageBoxButton.OK, MessageBoxImage.Information);
2023-10-08 23:15:24 -04:00
2025-06-17 16:35:03 -04:00
var mediaInformationWindow = new MediaInformationWindow(options ?? new Options(), submissionInfo)
2023-10-08 23:15:24 -04:00
{
Focusable = true,
Owner = this,
ShowActivated = true,
ShowInTaskbar = true,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
};
2025-06-17 16:35:03 -04:00
mediaInformationWindow.Closed += delegate { Activate(); };
bool? result = mediaInformationWindow.ShowDialog();
2023-10-08 23:15:24 -04:00
// Copy back the submission info changes, if necessary
if (result == true)
2025-06-17 16:35:03 -04:00
submissionInfo = (mediaInformationWindow.MediaInformationViewModel.SubmissionInfo.Clone() as SubmissionInfo)!;
2023-10-08 23:15:24 -04:00
return result;
2023-10-08 23:15:24 -04:00
}
/// <summary>
/// Show the Check Dump window
/// </summary>
public void ShowCheckDumpWindow()
{
// Hide MainWindow while Check GUI is open
2024-11-21 11:49:14 -05:00
Hide();
var checkDumpWindow = new CheckDumpWindow(this)
{
Focusable = true,
Owner = this,
ShowActivated = true,
ShowInTaskbar = true,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
};
checkDumpWindow.Closed += delegate
{
// Unhide Main window after Check window has been closed
2024-11-21 11:49:14 -05:00
Show();
Activate();
};
checkDumpWindow.Show();
}
/// <summary>
/// Show the Create IRD window
/// </summary>
public void ShowCreateIRDWindow()
{
// Hide MainWindow while Create IRD UI is open
2024-11-21 11:49:14 -05:00
Hide();
var createIRDWindow = new CreateIRDWindow(this)
{
Focusable = true,
Owner = this,
ShowActivated = true,
ShowInTaskbar = true,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
};
createIRDWindow.Closed += delegate
{
// Unhide Main window after Create IRD window has been closed
2024-11-21 11:49:14 -05:00
Show();
Activate();
};
createIRDWindow.Show();
}
2023-10-08 20:52:29 -04:00
/// <summary>
2023-10-08 22:49:46 -04:00
/// Show the Options window
2023-10-08 20:52:29 -04:00
/// </summary>
public void ShowOptionsWindow(string? title = null)
2023-10-08 20:52:29 -04:00
{
2023-10-08 22:49:46 -04:00
var optionsWindow = new OptionsWindow(MainViewModel.Options)
2023-10-08 20:52:29 -04:00
{
2023-10-08 22:49:46 -04:00
Focusable = true,
Owner = this,
ShowActivated = true,
ShowInTaskbar = true,
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
Title = title ?? (string)Application.Current.FindResource("OptionsTitleString"),
2023-10-08 22:49:46 -04:00
WindowStartupLocation = WindowStartupLocation.CenterOwner,
};
2024-11-21 11:49:14 -05:00
optionsWindow.Closed += delegate { Activate(); };
optionsWindow.Closed += OnOptionsUpdated;
2023-10-08 22:49:46 -04:00
optionsWindow.Show();
2023-10-08 20:52:29 -04:00
}
/// <summary>
/// Set media type combo box visibility based on current program
/// </summary>
public void SetMediaTypeVisibility()
{
2025-09-25 08:54:33 -04:00
// Only DiscImageCreator uses the media type box
if (MainViewModel.CurrentProgram != InternalProgram.DiscImageCreator)
{
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
SystemMediaTypeLabel!.Content = (string)Application.Current.FindResource("SystemLabelString");
2025-09-25 08:54:33 -04:00
MediaTypeComboBox!.Visibility = Visibility.Hidden;
return;
}
// If there are no media types defined
2026-01-25 18:09:00 -05:00
if (MainViewModel.MediaTypes is null)
2025-09-25 08:54:33 -04:00
{
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
SystemMediaTypeLabel!.Content = (string)Application.Current.FindResource("SystemLabelString");
2025-09-25 08:54:33 -04:00
MediaTypeComboBox!.Visibility = Visibility.Hidden;
return;
}
// Only systems with more than one media type should show the box
bool visible = MainViewModel.MediaTypes.Count > 1;
SystemMediaTypeLabel!.Content = visible
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
? (string)Application.Current.FindResource("SystemMediaTypeLabelString")
: (string)Application.Current.FindResource("SystemLabelString");
MediaTypeComboBox!.Visibility = visible
? Visibility.Visible
: Visibility.Hidden;
}
2023-10-18 10:21:40 -04:00
/// <summary>
/// Set the UI color scheme according to the options
/// </summary>
private void ApplyTheme()
{
2023-10-18 10:31:58 -04:00
Theme theme;
2023-10-18 10:21:40 -04:00
if (MainViewModel.Options.EnableDarkMode)
2023-10-18 10:31:58 -04:00
theme = new DarkModeTheme();
2024-06-24 10:46:15 +09:00
else if (MainViewModel.Options.EnablePurpMode)
theme = new CustomTheme("111111", "9A5EC0");
else if (IsHexColor(MainViewModel.Options.CustomBackgroundColor) && IsHexColor(MainViewModel.Options.CustomTextColor))
theme = new CustomTheme(MainViewModel.Options.CustomBackgroundColor, MainViewModel.Options.CustomTextColor);
2023-10-18 10:21:40 -04:00
else
2023-10-18 10:31:58 -04:00
theme = new LightModeTheme();
2023-10-09 11:35:49 -04:00
theme.Apply();
}
/// <summary>
/// Check whether a string represents a valid hex color
/// </summary>
public static bool IsHexColor(string? color)
{
if (string.IsNullOrWhiteSpace(color))
return false;
if (color!.Length == 7 && color[0] == '#')
2025-11-11 15:52:26 -05:00
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
color = color[1..];
#else
color = color.Substring(1);
2025-11-11 15:52:26 -05:00
#endif
2025-11-25 09:14:46 -05:00
if (color.Length != 6)
return false;
for (int i = 0; i < color.Length; i++)
{
switch (color[i])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
continue;
default:
break;
}
}
return true;
}
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
/// <summary>
2025-11-09 20:03:46 -05:00
/// Build the about text
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
/// </summary>
/// <returns></returns>
public string CreateAboutText()
{
string aboutText = $"{(string)Application.Current.FindResource("AppTitleFullString")}"
+ $"{Environment.NewLine}"
+ $"{Environment.NewLine}{(string)Application.Current.FindResource("AboutLine1String")}"
+ $"{Environment.NewLine}{(string)Application.Current.FindResource("AboutLine2String")}"
+ $"{Environment.NewLine}{(string)Application.Current.FindResource("AboutLine3String")}"
+ $"{Environment.NewLine}"
+ $"{Environment.NewLine}{(string)Application.Current.FindResource("AboutThanksString")}"
+ $"{Environment.NewLine}"
+ $"{Environment.NewLine}{(string)Application.Current.FindResource("VersionLabelString")} {FrontendTool.GetCurrentVersion()}";
MainViewModel.LogAboutText(aboutText);
return aboutText;
}
#endregion
2023-10-08 20:52:29 -04:00
#region Event Handlers
/// <summary>
/// Handler for OptionsWindow OnUpdated event
/// </summary>
2023-10-11 11:49:56 -04:00
public void OnOptionsUpdated(object? sender, EventArgs e)
{
// Get the options window
2026-01-25 18:09:00 -05:00
var optionsWindow = sender as OptionsWindow;
if (optionsWindow?.OptionsViewModel is null)
return;
2024-12-28 13:09:35 -05:00
// Get if the settings were saved
bool savedSettings = optionsWindow.OptionsViewModel.SavedSettings;
var options = optionsWindow.OptionsViewModel.Options;
2024-12-28 13:09:35 -05:00
// Force a refresh of the path, if necessary
if (MainViewModel.Options.DefaultOutputPath != options.DefaultOutputPath)
MainViewModel.OutputPath = string.Empty;
// Set the language according to the settings
if (savedSettings)
{
var oldDefaultLang = MainViewModel.Options.DefaultInterfaceLanguage;
var newDefaultLang = options.DefaultInterfaceLanguage;
if (oldDefaultLang != newDefaultLang)
{
SetInterfaceLanguage(newDefaultLang);
// Uncheck all language menu items
foreach (var item in LanguagesMenuItem.Items)
{
2025-11-11 15:52:26 -05:00
if (item is MenuItem menuItem && menuItem.IsCheckable)
menuItem.IsChecked = false;
}
}
}
2024-12-28 13:09:35 -05:00
// Update and save options, if necessary
MainViewModel.UpdateOptions(savedSettings, options);
2023-10-18 03:28:41 -04:00
// Set the UI color scheme according to the options
2023-10-18 10:21:40 -04:00
ApplyTheme();
// Hide or show the media type box based on program
SetMediaTypeVisibility();
}
2023-10-08 20:52:29 -04:00
#region Menu Bar
/// <summary>
/// Handler for AboutMenuItem Click event
/// </summary>
public void AboutClick(object sender, RoutedEventArgs e)
{
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
string aboutText = CreateAboutText();
CustomMessageBox.Show(this, aboutText, (string)Application.Current.FindResource("AboutTitleString"), MessageBoxButton.OK, MessageBoxImage.Information);
}
2023-10-08 20:52:29 -04:00
/// <summary>
/// Handler for AppExitMenuItem Click event
/// </summary>
2026-01-25 18:09:00 -05:00
public void AppExitClick(object sender, RoutedEventArgs e)
=> Application.Current.Shutdown();
2023-10-08 20:52:29 -04:00
/// <summary>
/// Handler for CheckDumpMenuItem Click event
/// </summary>
2026-01-25 18:09:00 -05:00
public void CheckDumpMenuItemClick(object sender, RoutedEventArgs e)
=> ShowCheckDumpWindow();
/// <summary>
/// Handler for CreateIRDMenuItem Click event
/// </summary>
2026-01-25 18:09:00 -05:00
public void CreateIRDMenuItemClick(object sender, RoutedEventArgs e)
=> ShowCreateIRDWindow();
2023-10-08 20:52:29 -04:00
/// <summary>
/// Handler for CheckForUpdatesMenuItem Click event
/// </summary>
public void CheckForUpdatesClick(object sender, RoutedEventArgs e)
=> CheckForUpdates(showIfSame: true);
2023-10-08 20:52:29 -04:00
/// <summary>
/// Handler for DebugViewMenuItem Click event
/// </summary>
2026-01-25 18:09:00 -05:00
public void DebugViewClick(object sender, RoutedEventArgs e)
=> ShowDebugDiscInfoWindow();
2023-10-08 20:52:29 -04:00
/// <summary>
/// Handler for OptionsMenuItem Click event
/// </summary>
2026-01-25 18:09:00 -05:00
public void OptionsMenuItemClick(object sender, RoutedEventArgs e)
=> ShowOptionsWindow();
2023-10-08 20:52:29 -04:00
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
/// <summary>
/// Change UI language
/// </summary>
private void LanguageMenuItemClick(object sender, RoutedEventArgs e)
{
// Don't do anything if language is already checked and being unchecked
var clickedItem = (MenuItem)sender;
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
if (!clickedItem.IsChecked)
{
clickedItem.IsChecked = true;
return;
}
// Uncheck every item not checked
var languageMenu = (MenuItem)clickedItem.Parent;
foreach (var item in languageMenu.Items)
{
if (item is MenuItem menuItem && menuItem != clickedItem)
menuItem.IsChecked = false;
}
// Change UI language to selected item
2025-10-17 08:10:02 -04:00
string lang = clickedItem.Header.ToString() ?? string.Empty;
SetInterfaceLanguage(EnumExtensions.ToInterfaceLanguage(lang));
Initial UI lang code (#899) * Test using resources * Include system namespace in resource xaml * system namespace name * rename strings * Default strings * Window resources * add keys * just one key * Combo box example * window resources * Dropdown in menu bar * nullable * non nullable * string list init * simple * English default * Add menu item for language * parent is menuitem * fix * no null lang * Only build win-x64, GHA storage limit * Korean * test * Set resource strings at app level * remove lost endif * Better UI * Move langs next to buttons * update * fix button * More translations * Better menu size * too many semicolons * top right menu bar * Tweaks * Top bar positioning * title bar width * try again * final * Back to original publish script * more windows * pre-merge test * Test non-latin underscore * More strings * fix * FindResource is a function * space * cast spells * Log about text * semicolon * Good * cast spells * using System.Windows in Frontend * Translate in MainViewModel * Dynamic GetFormattedVolumeLabel * Nullability * Fix * using for dict * Translate func in MVM * Don't translate in init * Update MVM translations * closing brace * Deprecate resource string * test * test2 * set current system * trial field * field is preview * default empty string * default null * fix build * empty string * GIve up on no system selected text * Fix context menu border * Revert half fix * Translate more IRD Window strings * Loose string * Detect current locale * fix * System.Globalization * Locale detection for default lang * break on zh case * default startup lang * default lang option * fix * fix2 * fix3 * nonnullable * final fix * final final fix * default language option * use default language on startup * empty entry * semicolon
2025-10-17 00:47:36 +09:00
// Update the labels that don't get updated automatically
SetMediaTypeVisibility();
}
2023-10-08 20:52:29 -04:00
#endregion
#region User Area
/// <summary>
/// Handler for CopyProtectScanButton Click event
/// </summary>
public async void CopyProtectScanButtonClick(object sender, RoutedEventArgs e)
{
var output = await MainViewModel.ScanAndShowProtection();
if (!MainViewModel.LogPanelExpanded)
{
if (!string.IsNullOrEmpty(output))
CustomMessageBox.Show(this, output, (string)Application.Current.FindResource("ProtectionDetectedTitleString"),
MessageBoxButton.OK, MessageBoxImage.Information);
else
CustomMessageBox.Show(this, (string)Application.Current.FindResource("ProtectionErrorMessageString"),
(string)Application.Current.FindResource("ProtectionErrorTitleString"), MessageBoxButton.OK, MessageBoxImage.Error);
}
}
2023-10-08 20:52:29 -04:00
/// <summary>
/// Handler for DriveLetterComboBox SelectionChanged event
/// </summary>
public void DriveLetterComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (MainViewModel.CanExecuteSelectionChanged)
2024-12-20 21:46:03 -05:00
MainViewModel.InitializeUIValues(removeEventHandlers: true, rebuildPrograms: false, rescanDrives: false);
2023-10-08 20:52:29 -04:00
}
/// <summary>
/// Handler for DriveSpeedComboBox SelectionChanged event
/// </summary>
public void DriveSpeedComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (MainViewModel.CanExecuteSelectionChanged)
2025-06-17 16:35:03 -04:00
MainViewModel.EnsureMediaInformation();
2023-10-08 20:52:29 -04:00
}
/// <summary>
/// Handler for DumpingProgramComboBox SelectionChanged event
/// </summary>
public void DumpingProgramComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (MainViewModel.CanExecuteSelectionChanged)
{
2023-10-08 20:52:29 -04:00
MainViewModel.ChangeDumpingProgram();
SetMediaTypeVisibility();
}
2023-10-08 20:52:29 -04:00
}
/// <summary>
/// Handler for EnableParametersCheckBox Click event
/// </summary>
2023-10-08 22:49:46 -04:00
public void EnableParametersCheckBoxClick(object sender, RoutedEventArgs e)
{
if (MainViewModel.CanExecuteSelectionChanged)
MainViewModel.ToggleParameters();
}
2023-10-08 20:52:29 -04:00
/// <summary>
/// Handler for MediaScanButton Click event
/// </summary>
2026-01-25 18:09:00 -05:00
public void MediaScanButtonClick(object sender, RoutedEventArgs e)
=> MainViewModel.InitializeUIValues(removeEventHandlers: true, rebuildPrograms: false, rescanDrives: true);
2023-10-08 20:52:29 -04:00
/// <summary>
/// Handler for MediaTypeComboBox SelectionChanged event
/// </summary>
public void MediaTypeComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (MainViewModel.CanExecuteSelectionChanged)
2023-10-09 00:13:40 -04:00
MainViewModel.ChangeMediaType(e.RemovedItems, e.AddedItems);
2023-10-08 20:52:29 -04:00
}
/// <summary>
/// Handler for OutputPathBrowseButton Click event
/// </summary>
2023-10-08 23:46:24 -04:00
public void OutputPathBrowseButtonClick(object sender, RoutedEventArgs e)
{
BrowseFile();
2025-06-17 16:35:03 -04:00
MainViewModel.EnsureMediaInformation();
2023-10-08 23:46:24 -04:00
}
2023-10-08 20:52:29 -04:00
/// <summary>
/// Handler for OutputPathTextBox TextChanged event
/// </summary>
public void OutputPathTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
if (MainViewModel.CanExecuteSelectionChanged)
2025-06-17 16:35:03 -04:00
MainViewModel.EnsureMediaInformation();
2023-10-08 20:52:29 -04:00
}
/// <summary>
/// Handler for StartStopButton Click event
/// </summary>
2026-01-25 18:09:00 -05:00
public void StartStopButtonClick(object sender, RoutedEventArgs e)
=> MainViewModel.ToggleStartStop();
2023-10-08 20:52:29 -04:00
/// <summary>
/// Handler for SystemTypeComboBox SelectionChanged event
/// </summary>
public void SystemTypeComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (MainViewModel.CanExecuteSelectionChanged)
{
2023-10-08 20:52:29 -04:00
MainViewModel.ChangeSystem();
SetMediaTypeVisibility();
}
2023-10-08 20:52:29 -04:00
}
/// <summary>
/// Handler for UpdateVolumeLabel Click event
/// </summary>
public void UpdateVolumeLabelClick(object sender, RoutedEventArgs e)
{
if (MainViewModel.CanExecuteSelectionChanged)
{
if (MainViewModel.Options.FastUpdateLabel)
MainViewModel.FastUpdateLabel(removeEventHandlers: true);
else
2024-12-20 21:46:03 -05:00
MainViewModel.InitializeUIValues(removeEventHandlers: true, rebuildPrograms: false, rescanDrives: false);
2023-10-08 20:52:29 -04:00
}
}
#endregion
#endregion // Event Handlers
2018-05-12 19:48:18 -04:00
}
}