Skip to content

Commit

Permalink
Merge pull request #1476 from LeLocTai/dev
Browse files Browse the repository at this point in the history
[Program Plugin] Support .url file and Steam/Epic shortcuts
  • Loading branch information
VictoriousRaptor authored Nov 1, 2022
2 parents 0dd25f0 + 81555ec commit e17ec6a
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 29 deletions.
6 changes: 4 additions & 2 deletions Flow.Launcher/ViewModel/ResultViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,17 @@ private async ValueTask LoadImageAsync()
}
}

var loadFullImage = (Path.GetExtension(imagePath) ?? "").Equals(".url", StringComparison.OrdinalIgnoreCase);

if (ImageLoader.CacheContainImage(imagePath))
{
// will get here either when icoPath has value\icon delegate is null\when had exception in delegate
image = ImageLoader.Load(imagePath);
image = ImageLoader.Load(imagePath, loadFullImage);
return;
}

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

public Result Result { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="ini-parser" Version="2.5.2" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
</ItemGroup>

Expand Down
17 changes: 15 additions & 2 deletions Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
xmlns:system="clr-namespace:System;assembly=mscorlib">

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

<system:String x:Key="flowlauncher_plugin_program_update">OK</system:String>
<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>
<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>
<system:String x:Key="flowlauncher_plugin_program_update_file_suffixes">Successfully updated file suffixes</system:String>
<system:String x:Key="flowlauncher_plugin_program_suffixes_cannot_empty">File suffixes can't be empty</system:String>
<system:String x:Key="flowlauncher_plugin_protocols_cannot_empty">Protocols can't be empty</system:String>

<system:String x:Key="flowlauncher_plugin_program_suffixes_excutable_types">File Suffixes</system:String>
<system:String x:Key="flowlauncher_plugin_program_suffixes_URL_types">URL Protocols</system:String>
<system:String x:Key="flowlauncher_plugin_program_suffixes_custom_urls">Custom URL Protocols</system:String>
<system:String x:Key="flowlauncher_plugin_program_suffixes_custom_file_types">Custom File Suffixes</system:String>
<system:String x:Key="flowlauncher_plugin_program_suffixes_tooltip">
Insert file suffixes you want to index. Suffixes should be separated by ';'. (ex>bat;py)
</system:String>
<system:String x:Key="flowlauncher_plugin_program_protocol_tooltip">
Insert protocols of .url files you want to index. Protocols should be separated by ';'. (ex>ftp;netflix)
</system:String>

<system:String x:Key="flowlauncher_plugin_program_run_as_different_user">Run As Different User</system:String>
<system:String x:Key="flowlauncher_plugin_program_run_as_administrator">Run As Administrator</system:String>
Expand Down
154 changes: 148 additions & 6 deletions Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,86 @@
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:ui="http://schemas.modernwpf.com/2019"
Title="{DynamicResource flowlauncher_plugin_program_suffixes}"
Width="400"
Width="600"
Background="{DynamicResource PopuBGColor}"
Foreground="{DynamicResource PopupTextColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
ResizeMode="NoResize"
SizeToContent="Height"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="32" ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
</WindowChrome.WindowChrome>
<Grid>
<Window.Resources>
<Style
x:Key="CustomFileTypeTextBox"
BasedOn="{StaticResource DefaultTextBoxStyle}"
TargetType="TextBox">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=CustomFiles, Path=IsChecked}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style
x:Key="CustomURLTypeTextBox"
BasedOn="{StaticResource DefaultTextBoxStyle}"
TargetType="TextBox">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=CustomProtocol, Path=IsChecked}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>

<Style x:Key="SettingGroupBoxSuffixToolTip" TargetType="Border">
<Setter Property="Background" Value="{DynamicResource Color00B}" />
<Setter Property="BorderBrush" Value="{DynamicResource Color03B}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="Margin" Value="0,5,0,0" />
<Setter Property="Padding" Value="15,15,15,15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=tbSuffixes, Path=IsFocused}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=tbSuffixes, Path=IsFocused}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>

<Style x:Key="SettingGroupBoxURLToolTip" TargetType="Border">
<Setter Property="Background" Value="{DynamicResource Color00B}" />
<Setter Property="BorderBrush" Value="{DynamicResource Color03B}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="Margin" Value="0,5,0,0" />
<Setter Property="Padding" Value="15,15,15,15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=tbProtocols, Path=IsFocused}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=tbProtocols, Path=IsFocused}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>

</Window.Resources>

<Grid x:Name="WindowArea">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="auto" />
<RowDefinition Height="80" />
</Grid.RowDefinitions>

Expand Down Expand Up @@ -55,7 +121,9 @@
</Grid>
</StackPanel>
<StackPanel Margin="26,12,26,0">

<StackPanel Margin="0,0,0,12">

<TextBlock
Grid.Column="0"
Margin="0,0,0,0"
Expand All @@ -65,10 +133,77 @@
TextAlignment="Left" />
</StackPanel>
<TextBlock
Margin="0,0,0,10"
FontSize="14"
Text="{DynamicResource flowlauncher_plugin_program_only_index_tip}"
TextWrapping="Wrap" />
<TextBox x:Name="tbSuffixes" Margin="0,20,0,20" />
<Border Style="{DynamicResource SettingGroupBoxURLToolTip}">
<TextBlock
FontSize="14"
Text="{DynamicResource flowlauncher_plugin_program_protocol_tooltip}"
TextWrapping="Wrap" />
</Border>

<Border Style="{DynamicResource SettingGroupBoxSuffixToolTip}">
<TextBlock
FontSize="14"
Text="{DynamicResource flowlauncher_plugin_program_suffixes_tooltip}"
TextWrapping="Wrap" />
</Border>

<Grid Margin="0,20,0,12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="250" />
</Grid.ColumnDefinitions>

<StackPanel Grid.Column="0" Margin="0,0,0,0">
<TextBlock
Margin="0,0,0,8"
FontSize="16"
FontWeight="SemiBold"
Text="{DynamicResource flowlauncher_plugin_program_suffixes_excutable_types}" />
<CheckBox Name="apprefMS" Margin="10,0,0,0" IsChecked="{Binding SuffixesStatus[appref-ms]}">appref-ms</CheckBox>
<CheckBox Name="exe" Margin="10,0,0,0" IsChecked="{Binding SuffixesStatus[exe]}">exe</CheckBox>
<CheckBox Name="lnk" Margin="10,0,0,0" IsChecked="{Binding SuffixesStatus[lnk]}">lnk</CheckBox>
<CheckBox
Name="CustomFiles"
Margin="10,0,0,0"
IsChecked="{Binding UseCustomSuffixes}"
Content="{DynamicResource flowlauncher_plugin_program_suffixes_custom_file_types}" />
<TextBox
x:Name="tbSuffixes"
Margin="10,4,0,6"
Style="{StaticResource CustomFileTypeTextBox}" />
</StackPanel>

<Border
Grid.Column="1"
Margin="20,0,0,10"
Padding="20,0,0,0"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="1,0,0,0">
<StackPanel>
<TextBlock
Margin="0,0,0,8"
FontSize="16"
FontWeight="SemiBold"
Text="{DynamicResource flowlauncher_plugin_program_suffixes_URL_types}" />
<CheckBox Name="steam" Margin="10,0,0,0" IsChecked="{Binding ProtocolsStatus[steam]}">Steam Games</CheckBox>
<CheckBox Name="epic" Margin="10,0,0,0" IsChecked="{Binding ProtocolsStatus[epic]}">Epic Games</CheckBox>
<CheckBox Name="http" Margin="10,0,0,0" IsChecked="{Binding ProtocolsStatus[http]}">Http/Https</CheckBox>
<CheckBox
Name="CustomProtocol"
Margin="10,0,0,0"
IsChecked="{Binding UseCustomProtocols}"
Content="{DynamicResource flowlauncher_plugin_program_suffixes_custom_urls}" />
<TextBox
x:Name="tbProtocols"
Margin="10,4,0,6"
Style="{StaticResource CustomURLTypeTextBox}" />
</StackPanel>
</Border>
</Grid>
</StackPanel>
</StackPanel>
<Border
Expand All @@ -78,10 +213,17 @@
BorderThickness="0,1,0,0">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button
x:Name="btnCancel"
x:Name="btnReset"
Height="30"
MinWidth="140"
Margin="0,0,5,0"
Click="BtnReset_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_reset}" />
<Button
x:Name="btnCancel"
Height="30"
MinWidth="140"
Margin="5,0,5,0"
Click="BtnCancel_OnClick"
Content="{DynamicResource cancel}" />

Expand All @@ -90,7 +232,7 @@
MinWidth="140"
Margin="5,0,0,0"
HorizontalAlignment="Right"
Click="ButtonBase_OnClick"
Click="BtnAdd_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_update}"
Style="{DynamicResource AccentButtonStyle}" />
</StackPanel>
Expand Down
56 changes: 44 additions & 12 deletions Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,44 +1,76 @@
using System;
using System.Collections.Generic;
using System.Windows;

namespace Flow.Launcher.Plugin.Program
{
/// <summary>
/// ProgramSuffixes.xaml 的交互逻辑
/// </summary>
public partial class ProgramSuffixes
{
private PluginInitContext context;
private Settings _settings;
public Dictionary<string, bool> SuffixesStatus { get; set; }
public Dictionary<string, bool> ProtocolsStatus { get; set; }
public bool UseCustomSuffixes { get; set; }
public bool UseCustomProtocols { get; set; }

public ProgramSuffixes(PluginInitContext context, Settings settings)
{
this.context = context;
InitializeComponent();
_settings = settings;
tbSuffixes.Text = string.Join(Settings.SuffixSeperator.ToString(), _settings.ProgramSuffixes);
SuffixesStatus = new Dictionary<string, bool>(_settings.BuiltinSuffixesStatus);
ProtocolsStatus = new Dictionary<string, bool>(_settings.BuiltinProtocolsStatus);
UseCustomSuffixes = _settings.UseCustomSuffixes;
UseCustomProtocols = _settings.UseCustomProtocols;
InitializeComponent();
tbSuffixes.Text = string.Join(Settings.SuffixSeparator, _settings.CustomSuffixes);
tbProtocols.Text = string.Join(Settings.SuffixSeparator, _settings.CustomProtocols);
}

private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
{
Close();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)

private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
{
var suffixes = tbSuffixes.Text.Split(Settings.SuffixSeperator, StringSplitOptions.RemoveEmptyEntries);
var suffixes = tbSuffixes.Text.Split(Settings.SuffixSeparator, StringSplitOptions.RemoveEmptyEntries);
var protocols = tbProtocols.Text.Split(Settings.SuffixSeparator, StringSplitOptions.RemoveEmptyEntries);

if (suffixes.Length == 0)
if (suffixes.Length == 0 && UseCustomSuffixes)
{
string warning = context.API.GetTranslation("flowlauncher_plugin_program_suffixes_cannot_empty");
MessageBox.Show(warning);
return;
}

_settings.ProgramSuffixes = suffixes;
if (protocols.Length == 0 && UseCustomProtocols)
{
string warning = context.API.GetTranslation("flowlauncher_plugin_protocols_cannot_empty");
MessageBox.Show(warning);
return;
}

string msg = context.API.GetTranslation("flowlauncher_plugin_program_update_file_suffixes");
MessageBox.Show(msg);
_settings.CustomSuffixes = suffixes;
_settings.CustomProtocols = protocols;
_settings.BuiltinSuffixesStatus = new Dictionary<string, bool>(SuffixesStatus);
_settings.BuiltinProtocolsStatus = new Dictionary<string, bool>(ProtocolsStatus);
_settings.UseCustomSuffixes = UseCustomSuffixes;
_settings.UseCustomProtocols = UseCustomProtocols;

DialogResult = true;
}

private void BtnReset_OnClick(object sender, RoutedEventArgs e)
{
apprefMS.IsChecked = true;
exe.IsChecked = true;
lnk.IsChecked = true;
CustomFiles.IsChecked = false;

steam.IsChecked = true;
epic.IsChecked = true;
http.IsChecked = false;
CustomProtocol.IsChecked = false;
}
}
}
}
Loading

0 comments on commit e17ec6a

Please sign in to comment.