Refactor AddProgramSource dialog

This commit is contained in:
Vic 2022-12-06 20:34:40 +08:00
parent 4d51ed91ec
commit 66dee47edc
4 changed files with 173 additions and 77 deletions

View file

@ -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" />
<TextBox
Name="Directory"
MinWidth="300"
Margin="10"
Text="{Binding Location, Mode=TwoWay}"
IsReadOnly="{Binding IsNotCustomSource}"
HorizontalAlignment="Stretch"
VerticalAlignment="Center" />
</DockPanel>
@ -119,6 +125,7 @@
Grid.Row="1"
Grid.Column="1"
Margin="10,0"
IsChecked="{Binding Enabled, Mode=TwoWay}"
VerticalAlignment="Center" />
</Grid>
</StackPanel>
@ -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}" />
</StackPanel>
</Border>

View file

@ -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
/// </summary>
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();
}
}
}

View file

@ -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));
}
}
}

View file

@ -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)