From 66dee47edc78b01021f8a3dca8ffa5c576d4d4b3 Mon Sep 17 00:00:00 2001 From: Vic <10308169+VictoriousRaptor@users.noreply.github.com> Date: Tue, 6 Dec 2022 20:34:40 +0800 Subject: [PATCH] Refactor AddProgramSource dialog --- .../AddProgramSource.xaml | 9 +- .../AddProgramSource.xaml.cs | 85 ++-------- .../ViewModels/AddProgramSourceViewModel.cs | 149 ++++++++++++++++++ .../Views/ProgramSetting.xaml.cs | 7 +- 4 files changed, 173 insertions(+), 77 deletions(-) create mode 100644 Plugins/Flow.Launcher.Plugin.Program/ViewModels/AddProgramSourceViewModel.cs diff --git a/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml b/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml index b1a8744fd..73a9190ac 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml +++ b/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml @@ -4,7 +4,10 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:vm="clr-namespace:Flow.Launcher.Plugin.Program.ViewModels" + mc:Ignorable="d" Title="{DynamicResource flowlauncher_plugin_program_directory}" + d:DataContext="{d:DesignInstance vm:AddProgramSourceViewModel}" Width="Auto" Height="276" Background="{DynamicResource PopuBGColor}" @@ -98,11 +101,14 @@ HorizontalAlignment="Stretch" Click="BrowseButton_Click" Content="{DynamicResource flowlauncher_plugin_program_browse}" + IsEnabled="{Binding IsCustomSource}" DockPanel.Dock="Right" /> @@ -119,6 +125,7 @@ Grid.Row="1" Grid.Column="1" Margin="10,0" + IsChecked="{Binding Enabled, Mode=TwoWay}" VerticalAlignment="Center" /> @@ -142,7 +149,7 @@ MinWidth="140" Margin="5,0,10,0" Click="BtnAdd_OnClick" - Content="{DynamicResource flowlauncher_plugin_program_update}" + Content="{Binding AddBtnText, Mode=TwoWay}" Style="{DynamicResource AccentButtonStyle}" /> diff --git a/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs index e88c9b988..ae6c5197e 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs @@ -1,8 +1,5 @@ using System.Windows; -using System.Windows.Forms; -using Flow.Launcher.Plugin.Program.Views.Models; -using Flow.Launcher.Plugin.Program.Views; -using System.Linq; +using Flow.Launcher.Plugin.Program.ViewModels; namespace Flow.Launcher.Plugin.Program { @@ -11,41 +8,18 @@ namespace Flow.Launcher.Plugin.Program /// public partial class AddProgramSource : Window { - private PluginInitContext _context; - private ProgramSource _editing; - private Settings _settings; - private bool update; + private readonly AddProgramSourceViewModel ViewModel; - public AddProgramSource(PluginInitContext context, Settings settings) + public AddProgramSource(AddProgramSourceViewModel viewModel) { + ViewModel = viewModel; + DataContext = viewModel; InitializeComponent(); - _context = context; - _settings = settings; - Directory.Focus(); - Chkbox.IsChecked = true; - update = false; - btnAdd.Content = _context.API.GetTranslation("flowlauncher_plugin_program_add"); - } - - public AddProgramSource(PluginInitContext context, Settings settings, ProgramSource source) - { - InitializeComponent(); - _context = context; - _editing = source; - _settings = settings; - update = true; - Chkbox.IsChecked = _editing.Enabled; - Directory.Text = _editing.Location; } private void BrowseButton_Click(object sender, RoutedEventArgs e) { - var dialog = new FolderBrowserDialog(); - DialogResult result = dialog.ShowDialog(); - if (result == System.Windows.Forms.DialogResult.OK) - { - Directory.Text = dialog.SelectedPath; - } + ViewModel.Browse(); } private void BtnCancel_OnClick(object sender, RoutedEventArgs e) @@ -55,53 +29,16 @@ namespace Flow.Launcher.Plugin.Program private void BtnAdd_OnClick(object sender, RoutedEventArgs e) { - string path = Directory.Text; - bool modified = false; - if (!System.IO.Directory.Exists(path)) + var status = ViewModel.AddOrUpdate(); + if (status == null) { - System.Windows.MessageBox.Show(_context.API.GetTranslation("flowlauncher_plugin_program_invalid_path")); - return; - } - if (!update) - { - if (!ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier.Equals(path, System.StringComparison.OrdinalIgnoreCase))) - { - var source = new ProgramSource(path); - modified = true; - _settings.ProgramSources.Insert(0, source); - ProgramSetting.ProgramSettingDisplayList.Add(source); - } - else - { - System.Windows.MessageBox.Show(_context.API.GetTranslation("flowlauncher_plugin_program_duplicate_program_source")); - return; - } + return; // Invalid } else { - // Separate checks to avoid changing UniqueIdentifier of UWP - if (!_editing.Location.Equals(path, System.StringComparison.OrdinalIgnoreCase)) - { - if (ProgramSetting.ProgramSettingDisplayList - .Any(x => x.UniqueIdentifier.Equals(path, System.StringComparison.OrdinalIgnoreCase))) - { - // Check if the new location is used - // No need to check win32 or uwp, just override them - System.Windows.MessageBox.Show(_context.API.GetTranslation("flowlauncher_plugin_program_duplicate_program_source")); - return; - } - modified = true; - _editing.Location = path; // Changes UniqueIdentifier internally - } - if (_editing.Enabled != Chkbox.IsChecked) - { - modified = true; - _editing.Enabled = Chkbox.IsChecked ?? true; - } + DialogResult = status ?? false; + Close(); } - - DialogResult = modified; - Close(); } } } diff --git a/Plugins/Flow.Launcher.Plugin.Program/ViewModels/AddProgramSourceViewModel.cs b/Plugins/Flow.Launcher.Plugin.Program/ViewModels/AddProgramSourceViewModel.cs new file mode 100644 index 000000000..92981b1fd --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.Program/ViewModels/AddProgramSourceViewModel.cs @@ -0,0 +1,149 @@ +using System; +using System.IO; +using System.Linq; +using System.Windows.Forms; +using Flow.Launcher.Plugin.Program.Views; +using Flow.Launcher.Plugin.Program.Views.Models; + +namespace Flow.Launcher.Plugin.Program.ViewModels +{ + public class AddProgramSourceViewModel : BaseModel + { + private readonly Settings Settings; + + private bool enabled = true; + public bool Enabled + { + get => enabled; + set + { + enabled = value; + OnPropertyChanged(nameof(Enabled)); + } + } + + private string location = string.Empty; + public string Location + { + get => location; + set + { + location = value; + OnPropertyChanged(nameof(Location)); + } + } + + public ProgramSource Source { get; init; } + public IPublicAPI API { get; init; } + public string AddBtnText { get; init; } + private bool LocationModified = false; + private bool StatusModified = false; + public bool IsCustomSource { get; init; } = true; + public bool IsNotCustomSource => !IsCustomSource; + + public AddProgramSourceViewModel(PluginInitContext context, Settings settings) + { + API = context.API; + Settings = settings; + AddBtnText = API.GetTranslation("flowlauncher_plugin_program_add"); + } + + public AddProgramSourceViewModel(PluginInitContext context, Settings settings, ProgramSource programSource) : this(context, settings) + { + Source = programSource; + enabled = Source.Enabled; + location = Source.Location; + AddBtnText = API.GetTranslation("flowlauncher_plugin_program_update"); + IsCustomSource = Settings.ProgramSources.Any(x => x.UniqueIdentifier == Source.UniqueIdentifier); + + this.PropertyChanged += (_, args) => + { + switch (args.PropertyName) + { + case nameof(Location): + LocationModified = true; + break; + case nameof(Enabled): + StatusModified = true; + break; + } + }; + } + + public void Browse() + { + var dialog = new FolderBrowserDialog(); + DialogResult result = dialog.ShowDialog(); + if (result == DialogResult.OK) + { + Location = dialog.SelectedPath; + } + } + + public bool? AddProgramSource() + { + if (!Directory.Exists(Location)) + { + System.Windows.MessageBox.Show(API.GetTranslation("flowlauncher_plugin_program_invalid_path")); + return null; + } + else if (DuplicateSource(Location)) + { + System.Windows.MessageBox.Show(API.GetTranslation("flowlauncher_plugin_program_duplicate_program_source")); + return null; + } + else + { + var source = new ProgramSource(Location, Enabled); + Settings.ProgramSources.Insert(0, source); + ProgramSetting.ProgramSettingDisplayList.Add(source); + return true; + } + } + + public bool? UpdateProgramSource() + { + // Separate checks to avoid changing UniqueIdentifier of UWP when changing Enabled + if (LocationModified) + { + if (!Directory.Exists(Location)) + { + System.Windows.MessageBox.Show(API.GetTranslation("flowlauncher_plugin_program_invalid_path")); + return null; + } + else if (DuplicateSource(Location)) + { + // No need to check win32 or uwp, just override them + System.Windows.MessageBox.Show(API.GetTranslation("flowlauncher_plugin_program_duplicate_program_source")); + return null; + } + else + { + Source.Location = Location; // Changes UniqueIdentifier internally + } + } + if (StatusModified) + { + Source.Enabled = Enabled; + } + return StatusModified || LocationModified; + } + + public bool? AddOrUpdate() + { + if (Source == null) + { + return AddProgramSource(); + } + else + { + return UpdateProgramSource(); + } + } + + public static bool DuplicateSource(string location) + { + return ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier.Equals(location, StringComparison.OrdinalIgnoreCase)); + } + } +} diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs index b8c2bca22..377ef5cf3 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs @@ -9,6 +9,7 @@ using Flow.Launcher.Plugin.Program.Views.Commands; using Flow.Launcher.Plugin.Program.Programs; using System.ComponentModel; using System.Windows.Data; +using Flow.Launcher.Plugin.Program.ViewModels; namespace Flow.Launcher.Plugin.Program.Views { @@ -135,7 +136,8 @@ namespace Flow.Launcher.Plugin.Program.Views private void btnAddProgramSource_OnClick(object sender, RoutedEventArgs e) { - var add = new AddProgramSource(context, _settings); + var vm = new AddProgramSourceViewModel(context, _settings); + var add = new AddProgramSource(vm); if (add.ShowDialog() ?? false) { ReIndexing(); @@ -170,7 +172,8 @@ namespace Flow.Launcher.Plugin.Program.Views } else { - var add = new AddProgramSource(context, _settings, selectedProgramSource); + var vm = new AddProgramSourceViewModel(context, _settings, selectedProgramSource); + var add = new AddProgramSource(vm); if (add.ShowDialog() ?? false) { if (selectedProgramSource.Enabled)