Skip to content

Commit 66dee47

Browse files
Refactor AddProgramSource dialog
1 parent 4d51ed9 commit 66dee47

File tree

4 files changed

+173
-77
lines changed

4 files changed

+173
-77
lines changed

Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
55
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7+
xmlns:vm="clr-namespace:Flow.Launcher.Plugin.Program.ViewModels"
8+
mc:Ignorable="d"
79
Title="{DynamicResource flowlauncher_plugin_program_directory}"
10+
d:DataContext="{d:DesignInstance vm:AddProgramSourceViewModel}"
811
Width="Auto"
912
Height="276"
1013
Background="{DynamicResource PopuBGColor}"
@@ -98,11 +101,14 @@
98101
HorizontalAlignment="Stretch"
99102
Click="BrowseButton_Click"
100103
Content="{DynamicResource flowlauncher_plugin_program_browse}"
104+
IsEnabled="{Binding IsCustomSource}"
101105
DockPanel.Dock="Right" />
102106
<TextBox
103107
Name="Directory"
104108
MinWidth="300"
105109
Margin="10"
110+
Text="{Binding Location, Mode=TwoWay}"
111+
IsReadOnly="{Binding IsNotCustomSource}"
106112
HorizontalAlignment="Stretch"
107113
VerticalAlignment="Center" />
108114
</DockPanel>
@@ -119,6 +125,7 @@
119125
Grid.Row="1"
120126
Grid.Column="1"
121127
Margin="10,0"
128+
IsChecked="{Binding Enabled, Mode=TwoWay}"
122129
VerticalAlignment="Center" />
123130
</Grid>
124131
</StackPanel>
@@ -142,7 +149,7 @@
142149
MinWidth="140"
143150
Margin="5,0,10,0"
144151
Click="BtnAdd_OnClick"
145-
Content="{DynamicResource flowlauncher_plugin_program_update}"
152+
Content="{Binding AddBtnText, Mode=TwoWay}"
146153
Style="{DynamicResource AccentButtonStyle}" />
147154
</StackPanel>
148155
</Border>
Lines changed: 11 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
using System.Windows;
2-
using System.Windows.Forms;
3-
using Flow.Launcher.Plugin.Program.Views.Models;
4-
using Flow.Launcher.Plugin.Program.Views;
5-
using System.Linq;
2+
using Flow.Launcher.Plugin.Program.ViewModels;
63

74
namespace Flow.Launcher.Plugin.Program
85
{
@@ -11,41 +8,18 @@ namespace Flow.Launcher.Plugin.Program
118
/// </summary>
129
public partial class AddProgramSource : Window
1310
{
14-
private PluginInitContext _context;
15-
private ProgramSource _editing;
16-
private Settings _settings;
17-
private bool update;
11+
private readonly AddProgramSourceViewModel ViewModel;
1812

19-
public AddProgramSource(PluginInitContext context, Settings settings)
13+
public AddProgramSource(AddProgramSourceViewModel viewModel)
2014
{
15+
ViewModel = viewModel;
16+
DataContext = viewModel;
2117
InitializeComponent();
22-
_context = context;
23-
_settings = settings;
24-
Directory.Focus();
25-
Chkbox.IsChecked = true;
26-
update = false;
27-
btnAdd.Content = _context.API.GetTranslation("flowlauncher_plugin_program_add");
28-
}
29-
30-
public AddProgramSource(PluginInitContext context, Settings settings, ProgramSource source)
31-
{
32-
InitializeComponent();
33-
_context = context;
34-
_editing = source;
35-
_settings = settings;
36-
update = true;
37-
Chkbox.IsChecked = _editing.Enabled;
38-
Directory.Text = _editing.Location;
3918
}
4019

4120
private void BrowseButton_Click(object sender, RoutedEventArgs e)
4221
{
43-
var dialog = new FolderBrowserDialog();
44-
DialogResult result = dialog.ShowDialog();
45-
if (result == System.Windows.Forms.DialogResult.OK)
46-
{
47-
Directory.Text = dialog.SelectedPath;
48-
}
22+
ViewModel.Browse();
4923
}
5024

5125
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
@@ -55,53 +29,16 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
5529

5630
private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
5731
{
58-
string path = Directory.Text;
59-
bool modified = false;
60-
if (!System.IO.Directory.Exists(path))
61-
{
62-
System.Windows.MessageBox.Show(_context.API.GetTranslation("flowlauncher_plugin_program_invalid_path"));
63-
return;
64-
}
65-
if (!update)
32+
var status = ViewModel.AddOrUpdate();
33+
if (status == null)
6634
{
67-
if (!ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier.Equals(path, System.StringComparison.OrdinalIgnoreCase)))
68-
{
69-
var source = new ProgramSource(path);
70-
modified = true;
71-
_settings.ProgramSources.Insert(0, source);
72-
ProgramSetting.ProgramSettingDisplayList.Add(source);
73-
}
74-
else
75-
{
76-
System.Windows.MessageBox.Show(_context.API.GetTranslation("flowlauncher_plugin_program_duplicate_program_source"));
77-
return;
78-
}
35+
return; // Invalid
7936
}
8037
else
8138
{
82-
// Separate checks to avoid changing UniqueIdentifier of UWP
83-
if (!_editing.Location.Equals(path, System.StringComparison.OrdinalIgnoreCase))
84-
{
85-
if (ProgramSetting.ProgramSettingDisplayList
86-
.Any(x => x.UniqueIdentifier.Equals(path, System.StringComparison.OrdinalIgnoreCase)))
87-
{
88-
// Check if the new location is used
89-
// No need to check win32 or uwp, just override them
90-
System.Windows.MessageBox.Show(_context.API.GetTranslation("flowlauncher_plugin_program_duplicate_program_source"));
91-
return;
92-
}
93-
modified = true;
94-
_editing.Location = path; // Changes UniqueIdentifier internally
95-
}
96-
if (_editing.Enabled != Chkbox.IsChecked)
97-
{
98-
modified = true;
99-
_editing.Enabled = Chkbox.IsChecked ?? true;
100-
}
39+
DialogResult = status ?? false;
40+
Close();
10141
}
102-
103-
DialogResult = modified;
104-
Close();
10542
}
10643
}
10744
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
using System;
2+
using System.IO;
3+
using System.Linq;
4+
using System.Windows.Forms;
5+
using Flow.Launcher.Plugin.Program.Views;
6+
using Flow.Launcher.Plugin.Program.Views.Models;
7+
8+
namespace Flow.Launcher.Plugin.Program.ViewModels
9+
{
10+
public class AddProgramSourceViewModel : BaseModel
11+
{
12+
private readonly Settings Settings;
13+
14+
private bool enabled = true;
15+
public bool Enabled
16+
{
17+
get => enabled;
18+
set
19+
{
20+
enabled = value;
21+
OnPropertyChanged(nameof(Enabled));
22+
}
23+
}
24+
25+
private string location = string.Empty;
26+
public string Location
27+
{
28+
get => location;
29+
set
30+
{
31+
location = value;
32+
OnPropertyChanged(nameof(Location));
33+
}
34+
}
35+
36+
public ProgramSource Source { get; init; }
37+
public IPublicAPI API { get; init; }
38+
public string AddBtnText { get; init; }
39+
private bool LocationModified = false;
40+
private bool StatusModified = false;
41+
public bool IsCustomSource { get; init; } = true;
42+
public bool IsNotCustomSource => !IsCustomSource;
43+
44+
public AddProgramSourceViewModel(PluginInitContext context, Settings settings)
45+
{
46+
API = context.API;
47+
Settings = settings;
48+
AddBtnText = API.GetTranslation("flowlauncher_plugin_program_add");
49+
}
50+
51+
public AddProgramSourceViewModel(PluginInitContext context, Settings settings, ProgramSource programSource) : this(context, settings)
52+
{
53+
Source = programSource;
54+
enabled = Source.Enabled;
55+
location = Source.Location;
56+
AddBtnText = API.GetTranslation("flowlauncher_plugin_program_update");
57+
IsCustomSource = Settings.ProgramSources.Any(x => x.UniqueIdentifier == Source.UniqueIdentifier);
58+
59+
this.PropertyChanged += (_, args) =>
60+
{
61+
switch (args.PropertyName)
62+
{
63+
case nameof(Location):
64+
LocationModified = true;
65+
break;
66+
case nameof(Enabled):
67+
StatusModified = true;
68+
break;
69+
}
70+
};
71+
}
72+
73+
public void Browse()
74+
{
75+
var dialog = new FolderBrowserDialog();
76+
DialogResult result = dialog.ShowDialog();
77+
if (result == DialogResult.OK)
78+
{
79+
Location = dialog.SelectedPath;
80+
}
81+
}
82+
83+
public bool? AddProgramSource()
84+
{
85+
if (!Directory.Exists(Location))
86+
{
87+
System.Windows.MessageBox.Show(API.GetTranslation("flowlauncher_plugin_program_invalid_path"));
88+
return null;
89+
}
90+
else if (DuplicateSource(Location))
91+
{
92+
System.Windows.MessageBox.Show(API.GetTranslation("flowlauncher_plugin_program_duplicate_program_source"));
93+
return null;
94+
}
95+
else
96+
{
97+
var source = new ProgramSource(Location, Enabled);
98+
Settings.ProgramSources.Insert(0, source);
99+
ProgramSetting.ProgramSettingDisplayList.Add(source);
100+
return true;
101+
}
102+
}
103+
104+
public bool? UpdateProgramSource()
105+
{
106+
// Separate checks to avoid changing UniqueIdentifier of UWP when changing Enabled
107+
if (LocationModified)
108+
{
109+
if (!Directory.Exists(Location))
110+
{
111+
System.Windows.MessageBox.Show(API.GetTranslation("flowlauncher_plugin_program_invalid_path"));
112+
return null;
113+
}
114+
else if (DuplicateSource(Location))
115+
{
116+
// No need to check win32 or uwp, just override them
117+
System.Windows.MessageBox.Show(API.GetTranslation("flowlauncher_plugin_program_duplicate_program_source"));
118+
return null;
119+
}
120+
else
121+
{
122+
Source.Location = Location; // Changes UniqueIdentifier internally
123+
}
124+
}
125+
if (StatusModified)
126+
{
127+
Source.Enabled = Enabled;
128+
}
129+
return StatusModified || LocationModified;
130+
}
131+
132+
public bool? AddOrUpdate()
133+
{
134+
if (Source == null)
135+
{
136+
return AddProgramSource();
137+
}
138+
else
139+
{
140+
return UpdateProgramSource();
141+
}
142+
}
143+
144+
public static bool DuplicateSource(string location)
145+
{
146+
return ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier.Equals(location, StringComparison.OrdinalIgnoreCase));
147+
}
148+
}
149+
}

Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Flow.Launcher.Plugin.Program.Programs;
1010
using System.ComponentModel;
1111
using System.Windows.Data;
12+
using Flow.Launcher.Plugin.Program.ViewModels;
1213

1314
namespace Flow.Launcher.Plugin.Program.Views
1415
{
@@ -135,7 +136,8 @@ private async void ReIndexing()
135136

136137
private void btnAddProgramSource_OnClick(object sender, RoutedEventArgs e)
137138
{
138-
var add = new AddProgramSource(context, _settings);
139+
var vm = new AddProgramSourceViewModel(context, _settings);
140+
var add = new AddProgramSource(vm);
139141
if (add.ShowDialog() ?? false)
140142
{
141143
ReIndexing();
@@ -170,7 +172,8 @@ private void EditProgramSource(ProgramSource selectedProgramSource)
170172
}
171173
else
172174
{
173-
var add = new AddProgramSource(context, _settings, selectedProgramSource);
175+
var vm = new AddProgramSourceViewModel(context, _settings, selectedProgramSource);
176+
var add = new AddProgramSource(vm);
174177
if (add.ShowDialog() ?? false)
175178
{
176179
if (selectedProgramSource.Enabled)

0 commit comments

Comments
 (0)