diff --git a/Source/NETworkManager.Utilities/SecureStringHelper.cs b/Source/NETworkManager.Utilities/SecureStringHelper.cs index a9e50f7489..e3370badb0 100644 --- a/Source/NETworkManager.Utilities/SecureStringHelper.cs +++ b/Source/NETworkManager.Utilities/SecureStringHelper.cs @@ -9,6 +9,7 @@ public static class SecureStringHelper public static string ConvertToString(SecureString secureString) { var valuePtr = IntPtr.Zero; + try { valuePtr = Marshal.SecureStringToGlobalAllocUnicode(secureString); diff --git a/Source/NETworkManager/DialogHelper.cs b/Source/NETworkManager/DialogHelper.cs new file mode 100644 index 0000000000..7fefe0fe5b --- /dev/null +++ b/Source/NETworkManager/DialogHelper.cs @@ -0,0 +1,98 @@ +using MahApps.Metro.SimpleChildWindow; +using NETworkManager.Localization.Resources; +using NETworkManager.Settings; +using NETworkManager.Utilities; +using NETworkManager.ViewModels; +using NETworkManager.Views; +using System.Threading.Tasks; +using System.Windows; + +namespace NETworkManager +{ + /// + /// Helper class for showing dialog messages. + /// + public static class DialogHelper + { + /// + /// Displays a modal message dialog with an OK button, allowing the user to acknowledge the message before + /// continuing. + /// + /// The dialog is shown as a child window of the specified parent. The method is + /// asynchronous and returns when the dialog is dismissed by the user. + /// The parent window that will host the message dialog. Cannot be null. + /// The title text displayed in the message dialog window. Cannot be null. + /// The main message content shown in the dialog. Cannot be null. + /// The icon to display in the dialog, indicating the message type. Defaults to Info if not specified. + /// The text to display on the OK button. If null, a default value is used. + /// A task that completes when the user closes the message dialog. + public static Task ShowOKMessageAsync(Window parentWindow, string title, string message, ChildWindowIcon icon = ChildWindowIcon.Info, string buttonOKText = null) + { + buttonOKText ??= Strings.OK; + + var childWindow = new OKMessageChildWindow(); + + var childWindowViewModel = new OKMessageViewModel(_ => + { + childWindow.IsOpen = false; + ConfigurationManager.Current.IsChildWindowOpen = false; + }, message, icon, buttonOKText); + + childWindow.Title = title; + + childWindow.DataContext = childWindowViewModel; + + ConfigurationManager.Current.IsChildWindowOpen = true; + + return parentWindow.ShowChildWindowAsync(childWindow); + } + + /// + /// Displays an asynchronous modal dialog with OK and Cancel buttons, allowing the user to confirm or cancel an + /// action. + /// + /// The dialog is shown as a child window of the specified parent. The method does not + /// return until the user closes the dialog. Custom button text and icon can be provided to tailor the dialog to + /// specific scenarios. + /// The parent window that hosts the child dialog. Cannot be null. + /// The title text displayed in the dialog window. + /// The message content shown to the user in the dialog. + /// The icon displayed in the dialog to indicate the message type. Defaults to Info. + /// The text label for the OK button. If null, a default value is used. + /// The text label for the Cancel button. If null, a default value is used. + /// A task that represents the asynchronous operation. The task result is if the user + /// clicks OK; otherwise, . + public static async Task ShowOKCancelMessageAsync(Window parentWindow, string title, string message, ChildWindowIcon icon = ChildWindowIcon.Info, string buttonOKText = null, string buttonCancelText = null) + { + buttonOKText ??= Strings.OK; + buttonCancelText ??= Strings.Cancel; + + var result = false; + + var childWindow = new OKCancelMessageChildWindow(); + + var childWindowViewModel = new OKCancelMessageViewModel(_ => + { + childWindow.IsOpen = false; + ConfigurationManager.Current.IsChildWindowOpen = false; + + result = true; + }, + _ => + { + childWindow.IsOpen = false; + ConfigurationManager.Current.IsChildWindowOpen = false; + }, + message, icon, buttonOKText, buttonCancelText); + + childWindow.Title = title; + childWindow.DataContext = childWindowViewModel; + + ConfigurationManager.Current.IsChildWindowOpen = true; + + await parentWindow.ShowChildWindowAsync(childWindow); + + return result; + } + } +} diff --git a/Source/NETworkManager/NETworkManager.csproj b/Source/NETworkManager/NETworkManager.csproj index 6a5b70c46c..6bfdefad2d 100644 --- a/Source/NETworkManager/NETworkManager.csproj +++ b/Source/NETworkManager/NETworkManager.csproj @@ -141,7 +141,7 @@ Wpf Designer - + MSBuild:Compile Wpf Designer diff --git a/Source/NETworkManager/ProfileDialogManager.cs b/Source/NETworkManager/ProfileDialogManager.cs index 5766dc423b..d36342fdff 100644 --- a/Source/NETworkManager/ProfileDialogManager.cs +++ b/Source/NETworkManager/ProfileDialogManager.cs @@ -6,6 +6,7 @@ using NETworkManager.Models.PuTTY; using NETworkManager.Models.RemoteDesktop; using NETworkManager.Profiles; +using NETworkManager.Utilities; using NETworkManager.ViewModels; using NETworkManager.Views; using System; @@ -560,39 +561,24 @@ public static Task ShowCopyAsProfileDialog(Window parentWindow, IProfileManagerM return parentWindow.ShowChildWindowAsync(childWindow); } - public static Task ShowDeleteProfileDialog(Window parentWindow, IProfileManagerMinimal viewModel, + public static async Task ShowDeleteProfileDialog(Window parentWindow, IProfileManagerMinimal viewModel, IList profiles) { - var childWindow = new OKCancelInfoMessageChildWindow(); - OKCancelInfoMessageViewModel childWindowViewModel = new(_ => - { - childWindow.IsOpen = false; - Settings.ConfigurationManager.Current.IsChildWindowOpen = false; - - viewModel.OnProfileManagerDialogClose(); - - ProfileManager.RemoveProfiles(profiles); - }, _ => - { - childWindow.IsOpen = false; - Settings.ConfigurationManager.Current.IsChildWindowOpen = false; - - viewModel.OnProfileManagerDialogClose(); - }, - profiles.Count == 1 ? Strings.DeleteProfileMessage : Strings.DeleteProfilesMessage, - Strings.Delete - ); - - childWindow.Title = profiles.Count == 1 ? Strings.DeleteProfile : Strings.DeleteProfiles; + viewModel.OnProfileManagerDialogOpen(); - childWindow.DataContext = childWindowViewModel; + var result = await DialogHelper.ShowOKCancelMessageAsync(parentWindow, + profiles.Count == 1 ? Strings.DeleteProfile : Strings.DeleteProfiles, + profiles.Count == 1 ? Strings.DeleteProfileMessage : Strings.DeleteProfilesMessage, + ChildWindowIcon.Info, + Strings.Delete); - viewModel.OnProfileManagerDialogOpen(); + viewModel.OnProfileManagerDialogClose(); - Settings.ConfigurationManager.Current.IsChildWindowOpen = true; + if (!result) + return; - return parentWindow.ShowChildWindowAsync(childWindow); + ProfileManager.RemoveProfiles(profiles); } #endregion @@ -662,40 +648,24 @@ public static Task ShowEditGroupDialog(Window parentWindow, IProfileManagerMinim return parentWindow.ShowChildWindowAsync(childWindow); } - public static Task ShowDeleteGroupDialog(Window parentWindow, IProfileManagerMinimal viewModel, + public static async Task ShowDeleteGroupDialog(Window parentWindow, IProfileManagerMinimal viewModel, GroupInfo group) { - var childWindow = new OKCancelInfoMessageChildWindow(); - - OKCancelInfoMessageViewModel childWindowViewModel = new(_ => - { - childWindow.IsOpen = false; - Settings.ConfigurationManager.Current.IsChildWindowOpen = false; - - viewModel.OnProfileManagerDialogClose(); - - ProfileManager.RemoveGroup(group); - }, _ => - { - childWindow.IsOpen = false; - Settings.ConfigurationManager.Current.IsChildWindowOpen = false; + viewModel.OnProfileManagerDialogOpen(); - viewModel.OnProfileManagerDialogClose(); - }, + var result = await DialogHelper.ShowOKCancelMessageAsync(parentWindow, + Strings.DeleteGroup, Strings.DeleteGroupMessage, - Strings.Delete - ); - - childWindow.Title = Strings.DeleteGroup; + ChildWindowIcon.Info, + Strings.Delete); - childWindow.DataContext = childWindowViewModel; + viewModel.OnProfileManagerDialogClose(); - viewModel.OnProfileManagerDialogOpen(); + if (!result) + return; - Settings.ConfigurationManager.Current.IsChildWindowOpen = true; - - return parentWindow.ShowChildWindowAsync(childWindow); + ProfileManager.RemoveGroup(group); } #endregion -} \ No newline at end of file +} diff --git a/Source/NETworkManager/ViewModels/AWSSessionManagerSettingsViewModel.cs b/Source/NETworkManager/ViewModels/AWSSessionManagerSettingsViewModel.cs index 8b87e4831d..fe0809c4c1 100644 --- a/Source/NETworkManager/ViewModels/AWSSessionManagerSettingsViewModel.cs +++ b/Source/NETworkManager/ViewModels/AWSSessionManagerSettingsViewModel.cs @@ -275,32 +275,19 @@ public async Task EditAWSProfile() await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog); } - private Task DeleteAWSProfile() + private async Task DeleteAWSProfile() { - var childWindow = new OKCancelInfoMessageChildWindow(); + var result = await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.DeleteAWSProfile, + Strings.DeleteAWSProfileMessage, + ChildWindowIcon.Info, + Strings.Delete); - var childWindowViewModel = new OKCancelInfoMessageViewModel(_ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - SettingsManager.Current.AWSSessionManager_AWSProfiles.Remove(SelectedAWSProfile); - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - }, - Strings.DeleteAWSProfileMessage, - Strings.Delete - ); + if (!result) + return; - childWindow.Title = Strings.DeleteAWSProfile; - - childWindow.DataContext = childWindowViewModel; - - ConfigurationManager.Current.IsChildWindowOpen = true; - - return (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + SettingsManager.Current.AWSSessionManager_AWSProfiles.Remove(SelectedAWSProfile); } private async Task Configure() diff --git a/Source/NETworkManager/ViewModels/DNSLookupSettingsViewModel.cs b/Source/NETworkManager/ViewModels/DNSLookupSettingsViewModel.cs index 40ae51f3a6..1bcfe63d1d 100644 --- a/Source/NETworkManager/ViewModels/DNSLookupSettingsViewModel.cs +++ b/Source/NETworkManager/ViewModels/DNSLookupSettingsViewModel.cs @@ -357,32 +357,18 @@ public async Task EditDNSServer() await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog); } - private Task DeleteDNSServer() + private async Task DeleteDNSServer() { - var childWindow = new OKCancelInfoMessageChildWindow(); + var result = await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.DeleteDNSServer, + Strings.DeleteDNSServerMessage, + ChildWindowIcon.Info, + Strings.Delete); - var childWindowViewModel = new OKCancelInfoMessageViewModel(_ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - - SettingsManager.Current.DNSLookup_DNSServers.Remove(SelectedDNSServer); - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - }, - Strings.DeleteDNSServerMessage, - Strings.Delete - ); - - childWindow.Title = Strings.DeleteDNSServer; - - childWindow.DataContext = childWindowViewModel; - - ConfigurationManager.Current.IsChildWindowOpen = true; + if (!result) + return; - return (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + SettingsManager.Current.DNSLookup_DNSServers.Remove(SelectedDNSServer); } #endregion diff --git a/Source/NETworkManager/ViewModels/HostsFileEditorViewModel.cs b/Source/NETworkManager/ViewModels/HostsFileEditorViewModel.cs index 847df2f759..041d5e720b 100644 --- a/Source/NETworkManager/ViewModels/HostsFileEditorViewModel.cs +++ b/Source/NETworkManager/ViewModels/HostsFileEditorViewModel.cs @@ -391,38 +391,28 @@ private async Task DeleteEntryAction() { IsModifying = true; - var childWindow = new OKCancelInfoMessageChildWindow(); - - var childWindowViewModel = new OKCancelInfoMessageViewModel(async _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - - var result = await HostsFileEditor.DeleteEntryAsync(SelectedResult); - - if (result != HostsFileEntryModifyResult.Success) - await ShowErrorMessageAsync(result); - - IsModifying = false; - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - - IsModifying = false; - }, + var result = await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.DeleteEntry, string.Format(Strings.DeleteHostsFileEntryMessage, SelectedResult.IPAddress, SelectedResult.Hostname, string.IsNullOrEmpty(SelectedResult.Comment) ? "" : $"# {SelectedResult.Comment}"), + ChildWindowIcon.Info, Strings.Delete - ); + ); - childWindow.Title = Strings.DeleteEntry; - childWindow.DataContext = childWindowViewModel; + if (!result) + { + IsModifying = false; + return; + } - ConfigurationManager.Current.IsChildWindowOpen = true; - await (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + var modifyResult = await HostsFileEditor.DeleteEntryAsync(SelectedResult); + + if (modifyResult != HostsFileEntryModifyResult.Success) + await ShowErrorMessageAsync(modifyResult); + + IsModifying = false; } private bool ModifyEntry_CanExecute(object obj) @@ -452,7 +442,7 @@ private async Task ShowErrorMessageAsync(HostsFileEntryModifyResult result) { childWindow.IsOpen = false; ConfigurationManager.Current.IsChildWindowOpen = false; - }, message, Strings.OK, ChildWindowIcon.Error); + }, message, ChildWindowIcon.Error, Strings.OK); childWindow.Title = Strings.Error; @@ -479,7 +469,7 @@ private async Task RestartAsAdminAction() { childWindow.IsOpen = false; ConfigurationManager.Current.IsChildWindowOpen = false; - }, ex.Message, Strings.OK, ChildWindowIcon.Error); + }, ex.Message, ChildWindowIcon.Error, Strings.OK); childWindow.Title = Strings.Error; diff --git a/Source/NETworkManager/ViewModels/IPScannerSettingsViewModel.cs b/Source/NETworkManager/ViewModels/IPScannerSettingsViewModel.cs index 055028e2d4..9c8095bd90 100644 --- a/Source/NETworkManager/ViewModels/IPScannerSettingsViewModel.cs +++ b/Source/NETworkManager/ViewModels/IPScannerSettingsViewModel.cs @@ -385,32 +385,18 @@ public async void EditCustomCommand() await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog); } - private Task DeleteCustomCommand() + private async Task DeleteCustomCommand() { - var childWindow = new OKCancelInfoMessageChildWindow(); + var result = await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.DeleteCustomCommand, + Strings.DeleteCustomCommandMessage, + ChildWindowIcon.Info, + Strings.Delete); - var childWindowViewModel = new OKCancelInfoMessageViewModel(_ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; + if (!result) + return; - SettingsManager.Current.IPScanner_CustomCommands.Remove(SelectedCustomCommand); - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - }, - Strings.DeleteCustomCommandMessage, - Strings.Delete - ); - - childWindow.Title = Strings.DeleteCustomCommand; - - childWindow.DataContext = childWindowViewModel; - - ConfigurationManager.Current.IsChildWindowOpen = true; - - return (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + SettingsManager.Current.IPScanner_CustomCommands.Remove(SelectedCustomCommand); } #endregion diff --git a/Source/NETworkManager/ViewModels/OKCancelInfoMessageViewModel.cs b/Source/NETworkManager/ViewModels/OKCancelMessageViewModel.cs similarity index 83% rename from Source/NETworkManager/ViewModels/OKCancelInfoMessageViewModel.cs rename to Source/NETworkManager/ViewModels/OKCancelMessageViewModel.cs index 69f4f83266..63f29342b8 100644 --- a/Source/NETworkManager/ViewModels/OKCancelInfoMessageViewModel.cs +++ b/Source/NETworkManager/ViewModels/OKCancelMessageViewModel.cs @@ -4,10 +4,10 @@ namespace NETworkManager.ViewModels; -public class OKCancelInfoMessageViewModel : ViewModelBase +public class OKCancelMessageViewModel : ViewModelBase { - public OKCancelInfoMessageViewModel(Action okCommand, - Action cancelHandler, string message, string okButtonText = null, string cancelButtonText = null, ChildWindowIcon icon = ChildWindowIcon.Info) + public OKCancelMessageViewModel(Action okCommand, + Action cancelHandler, string message, ChildWindowIcon icon = ChildWindowIcon.Info, string okButtonText = null, string cancelButtonText = null) { OKCommand = new RelayCommand(_ => okCommand(this)); CancelCommand = new RelayCommand(_ => cancelHandler(this)); diff --git a/Source/NETworkManager/ViewModels/OKMessageViewModel.cs b/Source/NETworkManager/ViewModels/OKMessageViewModel.cs index 3547003cb6..9044ec66c7 100644 --- a/Source/NETworkManager/ViewModels/OKMessageViewModel.cs +++ b/Source/NETworkManager/ViewModels/OKMessageViewModel.cs @@ -6,7 +6,7 @@ namespace NETworkManager.ViewModels; public class OKMessageViewModel : ViewModelBase { - public OKMessageViewModel(Action okCommand, string message, string okButtonText = null, ChildWindowIcon icon = ChildWindowIcon.Info) + public OKMessageViewModel(Action okCommand, string message, ChildWindowIcon icon = ChildWindowIcon.Info, string okButtonText = null) { OKCommand = new RelayCommand(_ => okCommand(this)); diff --git a/Source/NETworkManager/ViewModels/PortScannerSettingsViewModel.cs b/Source/NETworkManager/ViewModels/PortScannerSettingsViewModel.cs index 7aae52a9ca..d3b10a7ada 100644 --- a/Source/NETworkManager/ViewModels/PortScannerSettingsViewModel.cs +++ b/Source/NETworkManager/ViewModels/PortScannerSettingsViewModel.cs @@ -6,6 +6,7 @@ using NETworkManager.Utilities; using NETworkManager.Views; using System.ComponentModel; +using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Data; @@ -142,6 +143,8 @@ public PortScannerSettingsViewModel(IDialogCoordinator instance) PortProfiles.SortDescriptions.Add( new SortDescription(nameof(PortProfileInfo.Name), ListSortDirection.Ascending)); + SelectedPortProfile = PortProfiles.Cast().FirstOrDefault(); + LoadSettings(); _isLoading = false; @@ -232,30 +235,21 @@ public async Task EditPortProfile() await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog); } - private Task DeletePortProfile() + private async Task DeletePortProfile() { - var childWindow = new OKCancelInfoMessageChildWindow(); - - var childWindowViewModel = new OKCancelInfoMessageViewModel(_ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - - SettingsManager.Current.PortScanner_PortProfiles.Remove(SelectedPortProfile); - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - }, - Strings.DeletePortProfileMessage, Strings.Delete); - - childWindow.Title = Strings.DeletePortProfile; + var result = await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.DeletePortProfile, + Strings.DeletePortProfileMessage, + ChildWindowIcon.Info, + Strings.Delete); - childWindow.DataContext = childWindowViewModel; + if (!result) + return; - ConfigurationManager.Current.IsChildWindowOpen = true; + SettingsManager.Current.PortScanner_PortProfiles.Remove(SelectedPortProfile); - return (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + // Select first item after deletion + SelectedPortProfile = PortProfiles.Cast().FirstOrDefault(); } #endregion diff --git a/Source/NETworkManager/ViewModels/ProfileFileViewModel.cs b/Source/NETworkManager/ViewModels/ProfileFileViewModel.cs index 0474c56cab..f5a9c24ae3 100644 --- a/Source/NETworkManager/ViewModels/ProfileFileViewModel.cs +++ b/Source/NETworkManager/ViewModels/ProfileFileViewModel.cs @@ -11,10 +11,10 @@ public class ProfileFileViewModel : ViewModelBase private string _name; - public ProfileFileViewModel(Action addCommand, Action cancelHandler, + public ProfileFileViewModel(Action okCommand, Action cancelHandler, ProfileFileInfo info = null) { - AcceptCommand = new RelayCommand(_ => addCommand(this)); + OKCommand = new RelayCommand(_ => okCommand(this)); CancelCommand = new RelayCommand(_ => cancelHandler(this)); if (info == null) @@ -25,7 +25,7 @@ public ProfileFileViewModel(Action addCommand, Action - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; + if (!result) + return; - SettingsManager.Current.SNMP_OidProfiles.Remove(SelectedOIDProfile); - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - }, - Strings.DeleteOIDProfileMessage, Strings.Delete); - - childWindow.Title = Strings.DeleteOIDProfile; - - childWindow.DataContext = childWindowViewModel; - - ConfigurationManager.Current.IsChildWindowOpen = true; - - return (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + SettingsManager.Current.SNMP_OidProfiles.Remove(SelectedOIDProfile); } #endregion diff --git a/Source/NETworkManager/ViewModels/SNTPLookupSettingsViewModel.cs b/Source/NETworkManager/ViewModels/SNTPLookupSettingsViewModel.cs index 518bb12dcf..09ac160119 100644 --- a/Source/NETworkManager/ViewModels/SNTPLookupSettingsViewModel.cs +++ b/Source/NETworkManager/ViewModels/SNTPLookupSettingsViewModel.cs @@ -185,30 +185,18 @@ public async Task EditServer() await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog); } - private Task DeleteServer() + private async Task DeleteServer() { - var childWindow = new OKCancelInfoMessageChildWindow(); + var result = await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.DeleteSNTPServer, + Strings.DeleteSNTPServerMessage, + ChildWindowIcon.Info, + Strings.Delete); - var childWindowViewModel = new OKCancelInfoMessageViewModel(_ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - - SettingsManager.Current.SNTPLookup_SNTPServers.Remove(SelectedSNTPServer); - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - }, - Strings.DeleteSNTPServerMessage, Strings.Delete); - - childWindow.Title = Strings.DeleteSNTPServer; - - childWindow.DataContext = childWindowViewModel; - - ConfigurationManager.Current.IsChildWindowOpen = true; + if (!result) + return; - return (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + SettingsManager.Current.SNTPLookup_SNTPServers.Remove(SelectedSNTPServer); } #endregion diff --git a/Source/NETworkManager/ViewModels/SettingsProfilesViewModel.cs b/Source/NETworkManager/ViewModels/SettingsProfilesViewModel.cs index 1290260821..f6bd5260f7 100644 --- a/Source/NETworkManager/ViewModels/SettingsProfilesViewModel.cs +++ b/Source/NETworkManager/ViewModels/SettingsProfilesViewModel.cs @@ -133,46 +133,20 @@ private async Task AddProfileFileAction() await (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + // Re-select the profile file if (string.IsNullOrEmpty(profileName)) return; SelectedProfileFile = ProfileFiles.Cast() .FirstOrDefault(p => p.Name.Equals(profileName, StringComparison.OrdinalIgnoreCase)); - // Ask to enable encryption for the new profile file - if (await ShowEnableEncryptionMessage()) - EnableEncryptionAction(); - } - - private async Task ShowEnableEncryptionMessage() - { - var result = false; - - var childWindow = new OKCancelInfoMessageChildWindow(); - - var childWindowViewModel = new OKCancelInfoMessageViewModel(_ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - - result = true; - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - }, - Strings.EnableEncryptionForProfileFileMessage - ); - - childWindow.Title = Strings.EnableEncryptionQuestion; - - childWindow.DataContext = childWindowViewModel; + // Ask the user if they want to enable encryption for the new profile file + var result = await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.EnableEncryptionQuestion, + Strings.EnableEncryptionForProfileFileMessage); - ConfigurationManager.Current.IsChildWindowOpen = true; - - await (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); - - return result; + if (result) + EnableEncryptionAction(); } public ICommand EditProfileFileCommand => new RelayCommand(async _ => await EditProfileFileAction().ConfigureAwait(false)); @@ -205,6 +179,7 @@ private async Task EditProfileFileAction() await (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + // Re-select the profile file if (string.IsNullOrEmpty(profileName)) return; @@ -213,99 +188,67 @@ private async Task EditProfileFileAction() } public ICommand DeleteProfileFileCommand => - new RelayCommand(_ => DeleteProfileFileAction().ConfigureAwait(false), DeleteProfileFile_CanExecute); + new RelayCommand(async _ => await DeleteProfileFileAction().ConfigureAwait(false), DeleteProfileFile_CanExecute); private bool DeleteProfileFile_CanExecute(object obj) { return ProfileFiles.Cast().Count() > 1; } - private Task DeleteProfileFileAction() + private async Task DeleteProfileFileAction() { - var childWindow = new OKCancelInfoMessageChildWindow(); - - var childWindowViewModel = new OKCancelInfoMessageViewModel(_ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; + var result = await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.DeleteProfileFile, + string.Format(Strings.DeleteProfileFileXMessage, SelectedProfileFile.Name), + ChildWindowIcon.Info, + Strings.Delete); - ProfileManager.DeleteProfileFile(SelectedProfileFile); - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - }, - string.Format(Strings.DeleteProfileFileXMessage, SelectedProfileFile.Name), Strings.Delete); - - childWindow.Title = Strings.DeleteProfileFile; + if (!result) + return; - childWindow.DataContext = childWindowViewModel; + ProfileManager.DeleteProfileFile(SelectedProfileFile); - ConfigurationManager.Current.IsChildWindowOpen = true; - - return (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + // Select the first profile file + SelectedProfileFile = ProfileFiles.Cast().FirstOrDefault(); } - public ICommand EnableEncryptionCommand => new RelayCommand(_ => EnableEncryptionAction()); + public ICommand EnableEncryptionCommand => new RelayCommand(async _ => await EnableEncryptionAction().ConfigureAwait(false)); - private async void EnableEncryptionAction() + private async Task EnableEncryptionAction() { - if (!await ShowEncryptionDisclaimerAsync()) + // Show encryption disclaimer + if (!await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.Disclaimer, + Strings.ProfileEncryptionDisclaimer)) return; - var customDialog = new CustomDialog - { - Title = Strings.SetMasterPassword - }; - var credentialsSetPasswordViewModel = new CredentialsSetPasswordViewModel(async instance => - { - await _dialogCoordinator.HideMetroDialogAsync(this, customDialog); + var profileFile = SelectedProfileFile.Name; + + var childWindow = new CredentialsSetPasswordChildWindow(); + var childWindowViewModel = new CredentialsSetPasswordViewModel(async instance => + { + childWindow.IsOpen = false; + ConfigurationManager.Current.IsChildWindowOpen = false; try { ProfileManager.EnableEncryption(SelectedProfileFile, instance.Password); } catch (Exception ex) { - var metroDialogSettings = AppearanceManager.MetroDialog; - metroDialogSettings.AffirmativeButtonText = Strings.OK; - - await _dialogCoordinator.ShowMessageAsync(this, Strings.EncryptionError, + await DialogHelper.ShowOKMessageAsync(Application.Current.MainWindow, + Strings.EncryptionError, $"{Strings.EncryptionErrorMessage}\n\n{ex.Message}", - MessageDialogStyle.Affirmative, metroDialogSettings); + ChildWindowIcon.Error).ConfigureAwait(false); } - }, async _ => { await _dialogCoordinator.HideMetroDialogAsync(this, customDialog); }); - - customDialog.Content = new CredentialsSetPasswordDialog - { - DataContext = credentialsSetPasswordViewModel - }; - - await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog); - } - - private async Task ShowEncryptionDisclaimerAsync() - { - var result = false; - - var childWindow = new OKCancelInfoMessageChildWindow(); - - var childWindowViewModel = new OKCancelInfoMessageViewModel(_ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - - result = true; }, _ => { childWindow.IsOpen = false; ConfigurationManager.Current.IsChildWindowOpen = false; - }, - Strings.ProfileEncryptionDisclaimer - ); + }); - childWindow.Title = Strings.Disclaimer; + childWindow.Title = Strings.SetMasterPassword; childWindow.DataContext = childWindowViewModel; @@ -313,21 +256,26 @@ private async Task ShowEncryptionDisclaimerAsync() await (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); - return result; + // Re-select the profile file + if (string.IsNullOrEmpty(profileFile)) + return; + + SelectedProfileFile = ProfileFiles.Cast() + .FirstOrDefault(p => p.Name.Equals(profileFile, StringComparison.OrdinalIgnoreCase)); } - public ICommand ChangeMasterPasswordCommand => new RelayCommand(_ => ChangeMasterPasswordAction()); + public ICommand ChangeMasterPasswordCommand => new RelayCommand(async _ => await ChangeMasterPasswordAction().ConfigureAwait(false)); - private async void ChangeMasterPasswordAction() + private async Task ChangeMasterPasswordAction() { - var customDialog = new CustomDialog - { - Title = Strings.ChangeMasterPassword - }; + var profileName = SelectedProfileFile.Name; - var credentialsPasswordViewModel = new CredentialsChangePasswordViewModel(async instance => + var childWindow = new CredentialsChangePasswordChildWindow(); + + var childWindowViewModel = new CredentialsChangePasswordViewModel(async instance => { - await _dialogCoordinator.HideMetroDialogAsync(this, customDialog); + childWindow.IsOpen = false; + ConfigurationManager.Current.IsChildWindowOpen = false; try { @@ -335,44 +283,52 @@ private async void ChangeMasterPasswordAction() } catch (CryptographicException) { - var settings = AppearanceManager.MetroDialog; - settings.AffirmativeButtonText = Strings.OK; - - await _dialogCoordinator.ShowMessageAsync(this, Strings.WrongPassword, - Strings.WrongPasswordDecryptionFailedMessage, MessageDialogStyle.Affirmative, - settings); + await DialogHelper.ShowOKMessageAsync(Application.Current.MainWindow, + Strings.WrongPassword, + Strings.WrongPasswordDecryptionFailedMessage, + ChildWindowIcon.Error).ConfigureAwait(false); } catch (Exception ex) { - var settings = AppearanceManager.MetroDialog; - settings.AffirmativeButtonText = Strings.OK; - - await _dialogCoordinator.ShowMessageAsync(this, Strings.DecryptionError, + await DialogHelper.ShowOKMessageAsync(Application.Current.MainWindow, + Strings.DecryptionError, $"{Strings.DecryptionErrorMessage}\n\n{ex.Message}", - MessageDialogStyle.Affirmative, settings); + ChildWindowIcon.Error).ConfigureAwait(false); } - }, async _ => { await _dialogCoordinator.HideMetroDialogAsync(this, customDialog); }); - - customDialog.Content = new CredentialsChangePasswordDialog + }, _ => { - DataContext = credentialsPasswordViewModel - }; + childWindow.IsOpen = false; + ConfigurationManager.Current.IsChildWindowOpen = false; + }); + + childWindow.Title = Strings.ChangeMasterPassword; + + childWindow.DataContext = childWindowViewModel; + + ConfigurationManager.Current.IsChildWindowOpen = true; + + await (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + + // Re-select the profile file + if (string.IsNullOrEmpty(profileName)) + return; - await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog); + SelectedProfileFile = ProfileFiles.Cast() + .FirstOrDefault(p => p.Name.Equals(profileName, StringComparison.OrdinalIgnoreCase)); } - public ICommand DisableEncryptionCommand => new RelayCommand(_ => DisableEncryptionAction()); + public ICommand DisableEncryptionCommand => new RelayCommand(async _ => await DisableEncryptionAction().ConfigureAwait(false)); - private async void DisableEncryptionAction() + private async Task DisableEncryptionAction() { - var customDialog = new CustomDialog - { - Title = Strings.MasterPassword - }; + var profileName = SelectedProfileFile.Name; - var credentialsPasswordViewModel = new CredentialsPasswordViewModel(async instance => + var childWindow = new CredentialsPasswordChildWindow(); + + var childWindowViewModel = new CredentialsPasswordViewModel(async instance => { - await _dialogCoordinator.HideMetroDialogAsync(this, customDialog); + childWindow.IsOpen = false; + ConfigurationManager.Current.IsChildWindowOpen = false; try { @@ -380,31 +336,40 @@ private async void DisableEncryptionAction() } catch (CryptographicException) { - var settings = AppearanceManager.MetroDialog; - settings.AffirmativeButtonText = Strings.OK; - - await _dialogCoordinator.ShowMessageAsync(this, Strings.WrongPassword, - Strings.WrongPasswordDecryptionFailedMessage, MessageDialogStyle.Affirmative, - settings); + await DialogHelper.ShowOKMessageAsync(Application.Current.MainWindow, + Strings.WrongPassword, + Strings.WrongPasswordDecryptionFailedMessage, + ChildWindowIcon.Error).ConfigureAwait(false); } catch (Exception ex) { - var settings = AppearanceManager.MetroDialog; - settings.AffirmativeButtonText = Strings.OK; - - await _dialogCoordinator.ShowMessageAsync(this, Strings.DecryptionError, + await DialogHelper.ShowOKMessageAsync(Application.Current.MainWindow, + Strings.DecryptionError, $"{Strings.DecryptionErrorMessage}\n\n{ex.Message}", - MessageDialogStyle.Affirmative, settings); + ChildWindowIcon.Error).ConfigureAwait(false); } - }, async _1 => { await _dialogCoordinator.HideMetroDialogAsync(this, customDialog); }); - customDialog.Content = new CredentialsPasswordDialog - { - DataContext = credentialsPasswordViewModel - }; + }, _ => + { + childWindow.IsOpen = false; + ConfigurationManager.Current.IsChildWindowOpen = false; + }); + + childWindow.Title = Strings.MasterPassword; + + childWindow.DataContext = childWindowViewModel; - await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog); + ConfigurationManager.Current.IsChildWindowOpen = true; + + await (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + + // Re-select the profile file + if (string.IsNullOrEmpty(profileName)) + return; + + SelectedProfileFile = ProfileFiles.Cast() + .FirstOrDefault(p => p.Name.Equals(profileName, StringComparison.OrdinalIgnoreCase)); } #endregion -} \ No newline at end of file +} diff --git a/Source/NETworkManager/ViewModels/SettingsSettingsViewModel.cs b/Source/NETworkManager/ViewModels/SettingsSettingsViewModel.cs index aef50dee2f..d004a0d3bb 100644 --- a/Source/NETworkManager/ViewModels/SettingsSettingsViewModel.cs +++ b/Source/NETworkManager/ViewModels/SettingsSettingsViewModel.cs @@ -66,38 +66,22 @@ private void ResetSettingsAction() #region Methods - private Task ResetSettings() + private async Task ResetSettings() { - var childWindow = new OKCancelInfoMessageChildWindow(); - - var childWindowViewModel = new OKCancelInfoMessageViewModel(_ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - - // Init default settings - SettingsManager.Initialize(); - - // Restart the application - (Application.Current.MainWindow as MainWindow)?.RestartApplication(); - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - }, + var result = await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.ResetSettingsQuestion, Strings.SettingsAreResetAndApplicationWillBeRestartedMessage, - Strings.Reset, - Strings.Cancel, - ChildWindowIcon.Question - ); - - childWindow.Title = Strings.ResetSettingsQuestion; + ChildWindowIcon.Question, + Strings.Reset); - childWindow.DataContext = childWindowViewModel; + if (!result) + return; - ConfigurationManager.Current.IsChildWindowOpen = true; + // Init default settings + SettingsManager.Initialize(); - return (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + // Restart the application + (Application.Current.MainWindow as MainWindow)?.RestartApplication(); } #endregion } diff --git a/Source/NETworkManager/ViewModels/WebConsoleSettingsViewModel.cs b/Source/NETworkManager/ViewModels/WebConsoleSettingsViewModel.cs index 397412bae5..fcde9483e5 100644 --- a/Source/NETworkManager/ViewModels/WebConsoleSettingsViewModel.cs +++ b/Source/NETworkManager/ViewModels/WebConsoleSettingsViewModel.cs @@ -106,42 +106,28 @@ private void DeleteBrowsingDataAction() #region Methods - private Task DeleteBrowsingData() + private async Task DeleteBrowsingData() { - var childWindow = new OKCancelInfoMessageChildWindow(); - - var childWindowViewModel = new OKCancelInfoMessageViewModel(async _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - - // Create a temporary WebView2 instance to clear browsing data - var webView2Environment = - await CoreWebView2Environment.CreateAsync(null, GlobalStaticConfiguration.WebConsole_Cache); - - var windowHwnd = new WindowInteropHelper(Application.Current.MainWindow).Handle; - - var webView2Controller = await webView2Environment.CreateCoreWebView2ControllerAsync(windowHwnd); + var result = await DialogHelper.ShowOKCancelMessageAsync(Application.Current.MainWindow, + Strings.DeleteBrowsingData, + Strings.DeleteBrowsingDataMessage, + ChildWindowIcon.Info, + Strings.Delete); - await webView2Controller.CoreWebView2.Profile.ClearBrowsingDataAsync(); + if (!result) + return; - webView2Controller.Close(); - }, _ => - { - childWindow.IsOpen = false; - ConfigurationManager.Current.IsChildWindowOpen = false; - }, - Strings.DeleteBrowsingDataMessage, - Strings.Delete - ); + // Create a temporary WebView2 instance to clear browsing data + var webView2Environment = + await CoreWebView2Environment.CreateAsync(null, GlobalStaticConfiguration.WebConsole_Cache); - childWindow.Title = Strings.DeleteBrowsingData; + var windowHwnd = new WindowInteropHelper(Application.Current.MainWindow).Handle; - childWindow.DataContext = childWindowViewModel; + var webView2Controller = await webView2Environment.CreateCoreWebView2ControllerAsync(windowHwnd); - ConfigurationManager.Current.IsChildWindowOpen = true; + await webView2Controller.CoreWebView2.Profile.ClearBrowsingDataAsync(); - return (Application.Current.MainWindow as MainWindow).ShowChildWindowAsync(childWindow); + webView2Controller.Close(); } #endregion diff --git a/Source/NETworkManager/Views/CredentialsChangePasswordDialog.xaml b/Source/NETworkManager/Views/CredentialsChangePasswordChildWindow.xaml similarity index 80% rename from Source/NETworkManager/Views/CredentialsChangePasswordDialog.xaml rename to Source/NETworkManager/Views/CredentialsChangePasswordChildWindow.xaml index 5e176c0cc4..f1d9287417 100644 --- a/Source/NETworkManager/Views/CredentialsChangePasswordDialog.xaml +++ b/Source/NETworkManager/Views/CredentialsChangePasswordChildWindow.xaml @@ -1,4 +1,4 @@ - - + xmlns:simpleChildWindow="clr-namespace:MahApps.Metro.SimpleChildWindow;assembly=MahApps.Metro.SimpleChildWindow" + CloseButtonCommand="{Binding Path=CancelCommand}" + Style="{StaticResource DefaultChildWindow}" + Loaded="ChildWindow_OnLoaded" + mc:Ignorable="d" d:DataContext="{d:DesignInstance viewModels:CredentialsChangePasswordViewModel}"> + @@ -35,31 +38,31 @@ + Style="{StaticResource DefaultPasswordBox}"> + Password="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> + Style="{StaticResource DefaultPasswordBox}"> + Password="{Binding NewPassword, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> + Style="{StaticResource DefaultPasswordBox}"> + Password="{Binding NewPasswordRepeat, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> + Text="{x:Static localization:Strings.PasswordsDoNotMatch}" Margin="0,10,0,0">