Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand All @@ -15,6 +18,9 @@
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="32" ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
</WindowChrome.WindowChrome>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
Expand Down Expand Up @@ -98,11 +104,14 @@
HorizontalAlignment="Stretch"
Click="BrowseButton_Click"
Content="{DynamicResource flowlauncher_plugin_program_browse}"
Visibility="{Binding IsCustomSource, Converter={StaticResource BooleanToVisibilityConverter}}"
DockPanel.Dock="Right" />
<TextBox
Name="Directory"
Width="350"
Margin="10"
Text="{Binding Location, Mode=TwoWay}"
IsReadOnly="{Binding IsNotCustomSource}"
HorizontalAlignment="Stretch"
VerticalAlignment="Center" />
</DockPanel>
Expand All @@ -119,6 +128,7 @@
Grid.Row="1"
Grid.Column="1"
Margin="10,0"
IsChecked="{Binding Enabled, Mode=TwoWay}"
VerticalAlignment="Center" />
</Grid>
</StackPanel>
Expand All @@ -142,7 +152,7 @@
MinWidth="140"
Margin="5,0,10,0"
Click="BtnAdd_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_update}"
Content="{Binding AddBtnText}"
Style="{DynamicResource AccentButtonStyle}" />
</StackPanel>
</Border>
Expand Down
83 changes: 9 additions & 74 deletions Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand All @@ -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)
Expand All @@ -55,51 +29,12 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)

private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
{
string path = Directory.Text;
bool modified = false;
if (!System.IO.Directory.Exists(path))
var (modified, msg) = ViewModel.AddOrUpdate();
if (modified == false && msg != null)
{
System.Windows.MessageBox.Show(_context.API.GetTranslation("flowlauncher_plugin_program_invalid_path"));
MessageBox.Show(msg); // Invalid
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;
}
}
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 = modified;
Close();
}
Expand Down
33 changes: 0 additions & 33 deletions Plugins/Flow.Launcher.Plugin.Program/LocationConverter.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
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;
StatusModified = true;
}
}

private string location = string.Empty;
public string Location
{
get => location;
set
{
location = value;
LocationModified = true;
OnPropertyChanged();
}
}

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

public void Browse()
{
var dialog = new FolderBrowserDialog();
DialogResult result = dialog.ShowDialog();
if (result == DialogResult.OK)
{
Location = dialog.SelectedPath;
}
}

public (bool modified, string message) AddProgramSource()
{
if (!Directory.Exists(Location))
{
return (false, API.GetTranslation("flowlauncher_plugin_program_invalid_path"));
}
else if (DuplicateSource(Location))
{
return (false, API.GetTranslation("flowlauncher_plugin_program_duplicate_program_source"));
}
else
{
var source = new ProgramSource(Location, Enabled);
Settings.ProgramSources.Insert(0, source);
ProgramSetting.ProgramSettingDisplayList.Add(source);
return (true, null);
}
}

public (bool modified, string message) UpdateProgramSource()
{
if (LocationModified)
{
if (!Directory.Exists(Location))
{
return (false, API.GetTranslation("flowlauncher_plugin_program_invalid_path"));
}
else if (DuplicateSource(Location))
{
return (false, API.GetTranslation("flowlauncher_plugin_program_duplicate_program_source"));
}
else
{
Source.Location = Location; // Changes UniqueIdentifier internally
}
}
if (StatusModified)
{
Source.Enabled = Enabled;
}
return (StatusModified || LocationModified, null);
}

public (bool modified, string message) 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));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public bool Equals(IProgram program)

public override int GetHashCode()
{
return HashCode.Combine(UniqueIdentifier);
return uniqueIdentifier.GetHashCode();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
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:program="clr-namespace:Flow.Launcher.Plugin.Program"
Height="520"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d">
Expand Down Expand Up @@ -180,7 +179,7 @@
<GridViewColumn Header="{DynamicResource flowlauncher_plugin_program_location}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Location, ConverterParameter=(null), Converter={program:LocationConverter}}" TextTrimming="CharacterEllipsis" />
<TextBlock Text="{Binding Location}" TextTrimming="CharacterEllipsis" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Expand Down
13 changes: 10 additions & 3 deletions Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
using Flow.Launcher.Plugin.Program.Programs;
using System.ComponentModel;
using System.Windows.Data;
using System;
using Flow.Launcher.Plugin.Program.ViewModels;

namespace Flow.Launcher.Plugin.Program.Views
{
Expand Down Expand Up @@ -136,7 +136,8 @@ private async void ReIndexing()

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();
Expand Down Expand Up @@ -171,7 +172,12 @@ private void EditProgramSource(ProgramSource selectedProgramSource)
}
else
{
var add = new AddProgramSource(context, _settings, selectedProgramSource);
var vm = new AddProgramSourceViewModel(context, _settings, selectedProgramSource);
var add = new AddProgramSource(vm);
int selectedIndex = programSourceView.SelectedIndex;
// https://stackoverflow.com/questions/16789360/wpf-listbox-items-with-changing-hashcode
// Or it can't be unselected after changing Location
programSourceView.UnselectAll();
if (add.ShowDialog() ?? false)
{
if (selectedProgramSource.Enabled)
Expand All @@ -186,6 +192,7 @@ private void EditProgramSource(ProgramSource selectedProgramSource)
}
ReIndexing();
}
programSourceView.SelectedIndex = selectedIndex;
}
}

Expand Down