Skip to content

Commit e17ec6a

Browse files
Merge pull request #1476 from LeLocTai/dev
[Program Plugin] Support .url file and Steam/Epic shortcuts
2 parents 0dd25f0 + 81555ec commit e17ec6a

File tree

8 files changed

+336
-29
lines changed

8 files changed

+336
-29
lines changed

Flow.Launcher/ViewModel/ResultViewModel.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,17 @@ private async ValueTask LoadImageAsync()
163163
}
164164
}
165165

166+
var loadFullImage = (Path.GetExtension(imagePath) ?? "").Equals(".url", StringComparison.OrdinalIgnoreCase);
167+
166168
if (ImageLoader.CacheContainImage(imagePath))
167169
{
168170
// will get here either when icoPath has value\icon delegate is null\when had exception in delegate
169-
image = ImageLoader.Load(imagePath);
171+
image = ImageLoader.Load(imagePath, loadFullImage);
170172
return;
171173
}
172174

173175
// We need to modify the property not field here to trigger the OnPropertyChanged event
174-
Image = await Task.Run(() => ImageLoader.Load(imagePath)).ConfigureAwait(false);
176+
Image = await Task.Run(() => ImageLoader.Load(imagePath, loadFullImage)).ConfigureAwait(false);
175177
}
176178

177179
public Result Result { get; }

Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
</ItemGroup>
5959

6060
<ItemGroup>
61+
<PackageReference Include="ini-parser" Version="2.5.2" />
6162
<PackageReference Include="System.Runtime" Version="4.3.1" />
6263
</ItemGroup>
6364

Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
xmlns:system="clr-namespace:System;assembly=mscorlib">
55

66
<!-- Program setting -->
7+
<system:String x:Key="flowlauncher_plugin_program_reset">Reset Default</system:String>
78
<system:String x:Key="flowlauncher_plugin_program_delete">Delete</system:String>
89
<system:String x:Key="flowlauncher_plugin_program_edit">Edit</system:String>
910
<system:String x:Key="flowlauncher_plugin_program_add">Add</system:String>
@@ -12,7 +13,7 @@
1213
<system:String x:Key="flowlauncher_plugin_program_disable">Disable</system:String>
1314
<system:String x:Key="flowlauncher_plugin_program_location">Location</system:String>
1415
<system:String x:Key="flowlauncher_plugin_program_all_programs">All Programs</system:String>
15-
<system:String x:Key="flowlauncher_plugin_program_suffixes">File Suffixes</system:String>
16+
<system:String x:Key="flowlauncher_plugin_program_suffixes">File Type</system:String>
1617
<system:String x:Key="flowlauncher_plugin_program_reindex">Reindex</system:String>
1718
<system:String x:Key="flowlauncher_plugin_program_indexing">Indexing</system:String>
1819
<system:String x:Key="flowlauncher_plugin_program_index_start">Index Start Menu</system:String>
@@ -35,9 +36,21 @@
3536
<system:String x:Key="flowlauncher_plugin_program_delete_program_source">Are you sure you want to delete the selected program sources?</system:String>
3637

3738
<system:String x:Key="flowlauncher_plugin_program_update">OK</system:String>
38-
<system:String x:Key="flowlauncher_plugin_program_only_index_tip">Flow Launcher will only index files that end with the following suffixes. (Each suffix should split by ';' )</system:String>
39+
<system:String x:Key="flowlauncher_plugin_program_only_index_tip">Program Plugin will only index files with selected suffixes and .url files with selected protocols.</system:String>
3940
<system:String x:Key="flowlauncher_plugin_program_update_file_suffixes">Successfully updated file suffixes</system:String>
4041
<system:String x:Key="flowlauncher_plugin_program_suffixes_cannot_empty">File suffixes can't be empty</system:String>
42+
<system:String x:Key="flowlauncher_plugin_protocols_cannot_empty">Protocols can't be empty</system:String>
43+
44+
<system:String x:Key="flowlauncher_plugin_program_suffixes_excutable_types">File Suffixes</system:String>
45+
<system:String x:Key="flowlauncher_plugin_program_suffixes_URL_types">URL Protocols</system:String>
46+
<system:String x:Key="flowlauncher_plugin_program_suffixes_custom_urls">Custom URL Protocols</system:String>
47+
<system:String x:Key="flowlauncher_plugin_program_suffixes_custom_file_types">Custom File Suffixes</system:String>
48+
<system:String x:Key="flowlauncher_plugin_program_suffixes_tooltip">
49+
Insert file suffixes you want to index. Suffixes should be separated by ';'. (ex>bat;py)
50+
</system:String>
51+
<system:String x:Key="flowlauncher_plugin_program_protocol_tooltip">
52+
Insert protocols of .url files you want to index. Protocols should be separated by ';'. (ex>ftp;netflix)
53+
</system:String>
4154

4255
<system:String x:Key="flowlauncher_plugin_program_run_as_different_user">Run As Different User</system:String>
4356
<system:String x:Key="flowlauncher_plugin_program_run_as_administrator">Run As Administrator</system:String>

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

Lines changed: 148 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,86 @@
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:ui="http://schemas.modernwpf.com/2019"
78
Title="{DynamicResource flowlauncher_plugin_program_suffixes}"
8-
Width="400"
9+
Width="600"
910
Background="{DynamicResource PopuBGColor}"
1011
Foreground="{DynamicResource PopupTextColor}"
12+
DataContext="{Binding RelativeSource={RelativeSource Self}}"
1113
ResizeMode="NoResize"
1214
SizeToContent="Height"
1315
WindowStartupLocation="CenterScreen"
1416
mc:Ignorable="d">
1517
<WindowChrome.WindowChrome>
1618
<WindowChrome CaptionHeight="32" ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
1719
</WindowChrome.WindowChrome>
18-
<Grid>
20+
<Window.Resources>
21+
<Style
22+
x:Key="CustomFileTypeTextBox"
23+
BasedOn="{StaticResource DefaultTextBoxStyle}"
24+
TargetType="TextBox">
25+
<Setter Property="Visibility" Value="Collapsed" />
26+
<Style.Triggers>
27+
<DataTrigger Binding="{Binding ElementName=CustomFiles, Path=IsChecked}" Value="True">
28+
<Setter Property="Visibility" Value="Visible" />
29+
</DataTrigger>
30+
</Style.Triggers>
31+
</Style>
32+
<Style
33+
x:Key="CustomURLTypeTextBox"
34+
BasedOn="{StaticResource DefaultTextBoxStyle}"
35+
TargetType="TextBox">
36+
<Setter Property="Visibility" Value="Collapsed" />
37+
<Style.Triggers>
38+
<DataTrigger Binding="{Binding ElementName=CustomProtocol, Path=IsChecked}" Value="True">
39+
<Setter Property="Visibility" Value="Visible" />
40+
</DataTrigger>
41+
</Style.Triggers>
42+
</Style>
43+
44+
<Style x:Key="SettingGroupBoxSuffixToolTip" TargetType="Border">
45+
<Setter Property="Background" Value="{DynamicResource Color00B}" />
46+
<Setter Property="BorderBrush" Value="{DynamicResource Color03B}" />
47+
<Setter Property="BorderThickness" Value="1" />
48+
<Setter Property="CornerRadius" Value="5" />
49+
<Setter Property="Margin" Value="0,5,0,0" />
50+
<Setter Property="Padding" Value="15,15,15,15" />
51+
<Setter Property="SnapsToDevicePixels" Value="True" />
52+
<Setter Property="Visibility" Value="Collapsed" />
53+
<Style.Triggers>
54+
<DataTrigger Binding="{Binding ElementName=tbSuffixes, Path=IsFocused}" Value="True">
55+
<Setter Property="Visibility" Value="Visible" />
56+
</DataTrigger>
57+
<DataTrigger Binding="{Binding ElementName=tbSuffixes, Path=IsFocused}" Value="False">
58+
<Setter Property="Visibility" Value="Collapsed" />
59+
</DataTrigger>
60+
</Style.Triggers>
61+
</Style>
62+
63+
<Style x:Key="SettingGroupBoxURLToolTip" TargetType="Border">
64+
<Setter Property="Background" Value="{DynamicResource Color00B}" />
65+
<Setter Property="BorderBrush" Value="{DynamicResource Color03B}" />
66+
<Setter Property="BorderThickness" Value="1" />
67+
<Setter Property="CornerRadius" Value="5" />
68+
<Setter Property="Margin" Value="0,5,0,0" />
69+
<Setter Property="Padding" Value="15,15,15,15" />
70+
<Setter Property="SnapsToDevicePixels" Value="True" />
71+
<Setter Property="Visibility" Value="Collapsed" />
72+
<Style.Triggers>
73+
<DataTrigger Binding="{Binding ElementName=tbProtocols, Path=IsFocused}" Value="True">
74+
<Setter Property="Visibility" Value="Visible" />
75+
</DataTrigger>
76+
<DataTrigger Binding="{Binding ElementName=tbProtocols, Path=IsFocused}" Value="False">
77+
<Setter Property="Visibility" Value="Collapsed" />
78+
</DataTrigger>
79+
</Style.Triggers>
80+
</Style>
81+
82+
</Window.Resources>
83+
84+
<Grid x:Name="WindowArea">
1985
<Grid.RowDefinitions>
20-
<RowDefinition />
86+
<RowDefinition Height="auto" />
2187
<RowDefinition Height="80" />
2288
</Grid.RowDefinitions>
2389

@@ -55,7 +121,9 @@
55121
</Grid>
56122
</StackPanel>
57123
<StackPanel Margin="26,12,26,0">
124+
58125
<StackPanel Margin="0,0,0,12">
126+
59127
<TextBlock
60128
Grid.Column="0"
61129
Margin="0,0,0,0"
@@ -65,10 +133,77 @@
65133
TextAlignment="Left" />
66134
</StackPanel>
67135
<TextBlock
136+
Margin="0,0,0,10"
68137
FontSize="14"
69138
Text="{DynamicResource flowlauncher_plugin_program_only_index_tip}"
70139
TextWrapping="Wrap" />
71-
<TextBox x:Name="tbSuffixes" Margin="0,20,0,20" />
140+
<Border Style="{DynamicResource SettingGroupBoxURLToolTip}">
141+
<TextBlock
142+
FontSize="14"
143+
Text="{DynamicResource flowlauncher_plugin_program_protocol_tooltip}"
144+
TextWrapping="Wrap" />
145+
</Border>
146+
147+
<Border Style="{DynamicResource SettingGroupBoxSuffixToolTip}">
148+
<TextBlock
149+
FontSize="14"
150+
Text="{DynamicResource flowlauncher_plugin_program_suffixes_tooltip}"
151+
TextWrapping="Wrap" />
152+
</Border>
153+
154+
<Grid Margin="0,20,0,12">
155+
<Grid.ColumnDefinitions>
156+
<ColumnDefinition Width="250" />
157+
<ColumnDefinition Width="250" />
158+
</Grid.ColumnDefinitions>
159+
160+
<StackPanel Grid.Column="0" Margin="0,0,0,0">
161+
<TextBlock
162+
Margin="0,0,0,8"
163+
FontSize="16"
164+
FontWeight="SemiBold"
165+
Text="{DynamicResource flowlauncher_plugin_program_suffixes_excutable_types}" />
166+
<CheckBox Name="apprefMS" Margin="10,0,0,0" IsChecked="{Binding SuffixesStatus[appref-ms]}">appref-ms</CheckBox>
167+
<CheckBox Name="exe" Margin="10,0,0,0" IsChecked="{Binding SuffixesStatus[exe]}">exe</CheckBox>
168+
<CheckBox Name="lnk" Margin="10,0,0,0" IsChecked="{Binding SuffixesStatus[lnk]}">lnk</CheckBox>
169+
<CheckBox
170+
Name="CustomFiles"
171+
Margin="10,0,0,0"
172+
IsChecked="{Binding UseCustomSuffixes}"
173+
Content="{DynamicResource flowlauncher_plugin_program_suffixes_custom_file_types}" />
174+
<TextBox
175+
x:Name="tbSuffixes"
176+
Margin="10,4,0,6"
177+
Style="{StaticResource CustomFileTypeTextBox}" />
178+
</StackPanel>
179+
180+
<Border
181+
Grid.Column="1"
182+
Margin="20,0,0,10"
183+
Padding="20,0,0,0"
184+
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
185+
BorderThickness="1,0,0,0">
186+
<StackPanel>
187+
<TextBlock
188+
Margin="0,0,0,8"
189+
FontSize="16"
190+
FontWeight="SemiBold"
191+
Text="{DynamicResource flowlauncher_plugin_program_suffixes_URL_types}" />
192+
<CheckBox Name="steam" Margin="10,0,0,0" IsChecked="{Binding ProtocolsStatus[steam]}">Steam Games</CheckBox>
193+
<CheckBox Name="epic" Margin="10,0,0,0" IsChecked="{Binding ProtocolsStatus[epic]}">Epic Games</CheckBox>
194+
<CheckBox Name="http" Margin="10,0,0,0" IsChecked="{Binding ProtocolsStatus[http]}">Http/Https</CheckBox>
195+
<CheckBox
196+
Name="CustomProtocol"
197+
Margin="10,0,0,0"
198+
IsChecked="{Binding UseCustomProtocols}"
199+
Content="{DynamicResource flowlauncher_plugin_program_suffixes_custom_urls}" />
200+
<TextBox
201+
x:Name="tbProtocols"
202+
Margin="10,4,0,6"
203+
Style="{StaticResource CustomURLTypeTextBox}" />
204+
</StackPanel>
205+
</Border>
206+
</Grid>
72207
</StackPanel>
73208
</StackPanel>
74209
<Border
@@ -78,10 +213,17 @@
78213
BorderThickness="0,1,0,0">
79214
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
80215
<Button
81-
x:Name="btnCancel"
216+
x:Name="btnReset"
82217
Height="30"
83218
MinWidth="140"
84219
Margin="0,0,5,0"
220+
Click="BtnReset_OnClick"
221+
Content="{DynamicResource flowlauncher_plugin_program_reset}" />
222+
<Button
223+
x:Name="btnCancel"
224+
Height="30"
225+
MinWidth="140"
226+
Margin="5,0,5,0"
85227
Click="BtnCancel_OnClick"
86228
Content="{DynamicResource cancel}" />
87229

@@ -90,7 +232,7 @@
90232
MinWidth="140"
91233
Margin="5,0,0,0"
92234
HorizontalAlignment="Right"
93-
Click="ButtonBase_OnClick"
235+
Click="BtnAdd_OnClick"
94236
Content="{DynamicResource flowlauncher_plugin_program_update}"
95237
Style="{DynamicResource AccentButtonStyle}" />
96238
</StackPanel>
Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,76 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Windows;
34

45
namespace Flow.Launcher.Plugin.Program
56
{
6-
/// <summary>
7-
/// ProgramSuffixes.xaml 的交互逻辑
8-
/// </summary>
97
public partial class ProgramSuffixes
108
{
119
private PluginInitContext context;
1210
private Settings _settings;
11+
public Dictionary<string, bool> SuffixesStatus { get; set; }
12+
public Dictionary<string, bool> ProtocolsStatus { get; set; }
13+
public bool UseCustomSuffixes { get; set; }
14+
public bool UseCustomProtocols { get; set; }
1315

1416
public ProgramSuffixes(PluginInitContext context, Settings settings)
1517
{
1618
this.context = context;
17-
InitializeComponent();
1819
_settings = settings;
19-
tbSuffixes.Text = string.Join(Settings.SuffixSeperator.ToString(), _settings.ProgramSuffixes);
20+
SuffixesStatus = new Dictionary<string, bool>(_settings.BuiltinSuffixesStatus);
21+
ProtocolsStatus = new Dictionary<string, bool>(_settings.BuiltinProtocolsStatus);
22+
UseCustomSuffixes = _settings.UseCustomSuffixes;
23+
UseCustomProtocols = _settings.UseCustomProtocols;
24+
InitializeComponent();
25+
tbSuffixes.Text = string.Join(Settings.SuffixSeparator, _settings.CustomSuffixes);
26+
tbProtocols.Text = string.Join(Settings.SuffixSeparator, _settings.CustomProtocols);
2027
}
28+
2129
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
2230
{
2331
Close();
2432
}
25-
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
33+
34+
private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
2635
{
27-
var suffixes = tbSuffixes.Text.Split(Settings.SuffixSeperator, StringSplitOptions.RemoveEmptyEntries);
36+
var suffixes = tbSuffixes.Text.Split(Settings.SuffixSeparator, StringSplitOptions.RemoveEmptyEntries);
37+
var protocols = tbProtocols.Text.Split(Settings.SuffixSeparator, StringSplitOptions.RemoveEmptyEntries);
2838

29-
if (suffixes.Length == 0)
39+
if (suffixes.Length == 0 && UseCustomSuffixes)
3040
{
3141
string warning = context.API.GetTranslation("flowlauncher_plugin_program_suffixes_cannot_empty");
3242
MessageBox.Show(warning);
3343
return;
3444
}
3545

36-
_settings.ProgramSuffixes = suffixes;
46+
if (protocols.Length == 0 && UseCustomProtocols)
47+
{
48+
string warning = context.API.GetTranslation("flowlauncher_plugin_protocols_cannot_empty");
49+
MessageBox.Show(warning);
50+
return;
51+
}
3752

38-
string msg = context.API.GetTranslation("flowlauncher_plugin_program_update_file_suffixes");
39-
MessageBox.Show(msg);
53+
_settings.CustomSuffixes = suffixes;
54+
_settings.CustomProtocols = protocols;
55+
_settings.BuiltinSuffixesStatus = new Dictionary<string, bool>(SuffixesStatus);
56+
_settings.BuiltinProtocolsStatus = new Dictionary<string, bool>(ProtocolsStatus);
57+
_settings.UseCustomSuffixes = UseCustomSuffixes;
58+
_settings.UseCustomProtocols = UseCustomProtocols;
4059

4160
DialogResult = true;
4261
}
62+
63+
private void BtnReset_OnClick(object sender, RoutedEventArgs e)
64+
{
65+
apprefMS.IsChecked = true;
66+
exe.IsChecked = true;
67+
lnk.IsChecked = true;
68+
CustomFiles.IsChecked = false;
69+
70+
steam.IsChecked = true;
71+
epic.IsChecked = true;
72+
http.IsChecked = false;
73+
CustomProtocol.IsChecked = false;
74+
}
4375
}
44-
}
76+
}

0 commit comments

Comments
 (0)