using System; using System.IO; using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; using MPF.Frontend; using MPF.Frontend.ViewModels; using SabreTools.RedumpLib.Web; using WPFCustomMessageBox; namespace MPF.UI.Windows { /// /// Interaction logic for OptionsWindow.xaml /// public partial class OptionsWindow : WindowBase { /// /// Read-only access to the current options view model /// public OptionsViewModel OptionsViewModel => DataContext as OptionsViewModel ?? new OptionsViewModel(); #if NET35 private System.Windows.Controls.Button? AaruPathButton => ItemHelper.FindChild(this, "AaruPathButton"); private System.Windows.Controls.Button? AcceptButton => ItemHelper.FindChild(this, "AcceptButton"); private System.Windows.Controls.Button? CancelButton => ItemHelper.FindChild(this, "CancelButton"); private System.Windows.Controls.Button? DefaultOutputPathButton => ItemHelper.FindChild(this, "DefaultOutputPathButton"); private System.Windows.Controls.Button? DiscImageCreatorPathButton => ItemHelper.FindChild(this, "DiscImageCreatorPathButton"); private System.Windows.Controls.Button? RedumperPathButton => ItemHelper.FindChild(this, "RedumperPathButton"); private System.Windows.Controls.Button? RedumpLoginTestButton => ItemHelper.FindChild(this, "RedumpLoginTestButton"); private PasswordBox? RedumpPasswordBox => ItemHelper.FindChild(this, "RedumpPasswordBox"); private System.Windows.Controls.TextBox? RedumpUsernameTextBox => ItemHelper.FindChild(this, "RedumpUsernameTextBox"); #endif /// /// Constructor /// public OptionsWindow(Options options) { #if NET40_OR_GREATER || NETCOREAPP InitializeComponent(); #endif #if NET40_OR_GREATER || NETCOREAPP DumpSpeedCDTextBox.IsReadOnlyCaretVisible = false; DumpSpeedDVDTextBox.IsReadOnlyCaretVisible = false; DumpSpeedHDDVDTextBox.IsReadOnlyCaretVisible = false; DumpSpeedBDTextBox.IsReadOnlyCaretVisible = false; #endif #if NET452_OR_GREATER || NETCOREAPP var chrome = new System.Windows.Shell.WindowChrome { CaptionHeight = 0, ResizeBorderThickness = new Thickness(0), }; System.Windows.Shell.WindowChrome.SetWindowChrome(this, chrome); #endif DataContext = new OptionsViewModel(options); // Set initial value for binding RedumpPasswordBox!.Password = options.Processing.Login.RedumpPassword; // Add handlers AaruPathButton!.Click += BrowseForAaruPathClick; DiscImageCreatorPathButton!.Click += BrowseForDiscImageCreatorPathClick; RedumperPathButton!.Click += BrowseForRedumperPathClick; DefaultOutputPathButton!.Click += BrowseForDefaultOutputPathClick; AcceptButton!.Click += OnAcceptClick; CancelButton!.Click += OnCancelClick; RedumpPasswordBox!.PasswordChanged += OnPasswordChanged; RedumpLoginTestButton!.Click += OnRedumpTestClick; } /// /// Handler for OptionsWindow OnContentRendered event /// protected override void OnContentRendered(EventArgs e) { base.OnContentRendered(e); // Set the window title OptionsViewModel.Title = Title; } #region UI Commands /// /// Browse and set a path based on the invoking button /// private string? BrowseForPath(Window parent, System.Windows.Controls.Button? button) { // If the button is null, we can't do anything if (button is null) return null; // Strips button prefix to obtain the setting name #if NETCOREAPP || NETSTANDARD2_1_OR_GREATER string pathSettingName = button.Name[..button.Name.IndexOf("Button")]; #else string pathSettingName = button.Name.Substring(0, button.Name.IndexOf("Button")); #endif // TODO: hack for now, then we'll see bool shouldBrowseForPath = pathSettingName == "DefaultOutputPath"; var currentPath = TextBoxForPathSetting(parent, pathSettingName)?.Text; var initialDirectory = AppDomain.CurrentDomain.BaseDirectory; if (!shouldBrowseForPath && !string.IsNullOrEmpty(currentPath)) initialDirectory = Path.GetDirectoryName(Path.GetFullPath(currentPath)); CommonDialog dialog = shouldBrowseForPath ? CreateFolderBrowserDialog() : CreateOpenFileDialog(initialDirectory); using (dialog) { DialogResult result = dialog.ShowDialog(); if (result != System.Windows.Forms.DialogResult.OK) return null; string path = string.Empty; bool exists = false; if (shouldBrowseForPath && dialog is FolderBrowserDialog folderBrowserDialog) { path = folderBrowserDialog.SelectedPath; exists = Directory.Exists(path); } else if (dialog is OpenFileDialog openFileDialog) { path = openFileDialog.FileName; exists = File.Exists(path); } if (exists) { var textBox = TextBoxForPathSetting(parent, pathSettingName); textBox?.Text = path; } else { CustomMessageBox.Show( "Specified path doesn't exist!", (string)System.Windows.Application.Current.FindResource("ErrorMessageString"), MessageBoxButton.OK, MessageBoxImage.Error ); } return path; } } /// /// Find a TextBox by setting name /// /// Setting name to find /// TextBox for that setting private static System.Windows.Controls.TextBox? TextBoxForPathSetting(Window parent, string name) => parent.FindName(name + "TextBox") as System.Windows.Controls.TextBox; /// /// Create an open folder dialog box /// private static FolderBrowserDialog CreateFolderBrowserDialog() => new(); /// /// Create an open file dialog box /// private static OpenFileDialog CreateOpenFileDialog(string? initialDirectory) { return new OpenFileDialog() { InitialDirectory = initialDirectory, Filter = "Executables (*.exe)|*.exe", FilterIndex = 0, RestoreDirectory = true, }; } /// /// Test Redump credentials for validity /// private async Task ValidateRedumpCredentials() { bool? success = await RedumpClient.ValidateCredentials(RedumpUsernameTextBox!.Text, RedumpPasswordBox!.Password); string message = OptionsViewModel.GetRedumpLoginResult(success); if (success == true) CustomMessageBox.Show(this, message, "Success", MessageBoxButton.OK, MessageBoxImage.Information); else if (success == false) CustomMessageBox.Show(this, message, (string)System.Windows.Application.Current.FindResource("ErrorMessageString"), MessageBoxButton.OK, MessageBoxImage.Error); else CustomMessageBox.Show(this, message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); return success; } #endregion #region Event Handlers /// /// Handler for generic Click event /// private void BrowseForAaruPathClick(object sender, EventArgs e) { string? result = BrowseForPath(this, sender as System.Windows.Controls.Button); if (result is not null) OptionsViewModel.Options.Dumping.AaruPath = result; } /// /// Handler for generic Click event /// private void BrowseForDefaultOutputPathClick(object sender, EventArgs e) { string? result = BrowseForPath(this, sender as System.Windows.Controls.Button); if (result is not null) OptionsViewModel.Options.Dumping.DefaultOutputPath = result; } /// /// Handler for generic Click event /// private void BrowseForDiscImageCreatorPathClick(object sender, EventArgs e) { string? result = BrowseForPath(this, sender as System.Windows.Controls.Button); if (result is not null) OptionsViewModel.Options.Dumping.DiscImageCreatorPath = result; } /// /// Handler for generic Click event /// private void BrowseForRedumperPathClick(object sender, EventArgs e) { string? result = BrowseForPath(this, sender as System.Windows.Controls.Button); if (result is not null) OptionsViewModel.Options.Dumping.RedumperPath = result; } /// /// Alert user of non-redump mode implications /// private void NonRedumpModeClicked(object sender, EventArgs e) { if (OptionsViewModel.Options.Dumping.Redumper.NonRedumpMode) CustomMessageBox.Show(this, "All logs generated with these options will not be acceptable for Redump submission", (string)System.Windows.Application.Current.FindResource("WarningMessageString"), MessageBoxButton.OK, MessageBoxImage.Warning); else OptionsViewModel.NonRedumpModeUnChecked(); } /// /// Handler for AcceptButton Click event /// private void OnAcceptClick(object sender, EventArgs e) { OptionsViewModel.SavedSettings = true; Close(); } /// /// Handler for CancelButtom Click event /// private void OnCancelClick(object sender, EventArgs e) { OptionsViewModel.SavedSettings = false; Close(); } /// /// Handler for RedumpPasswordBox PasswordChanged event /// private void OnPasswordChanged(object sender, EventArgs e) { OptionsViewModel.Options.Processing.Login.RedumpPassword = RedumpPasswordBox!.Password; } /// /// Test Redump credentials for validity /// private async void OnRedumpTestClick(object sender, EventArgs e) => await ValidateRedumpCredentials(); #endregion } }