Merge branch 'dev' into update_ui

This commit is contained in:
Jeremy Wu 2020-05-08 12:41:57 +10:00
commit 47a69a322d
53 changed files with 511 additions and 128 deletions

View file

@ -172,7 +172,7 @@ namespace Flow.Launcher.Core.Configuration
"would you like to move it to a different location?", string.Empty, "would you like to move it to a different location?", string.Empty,
MessageBoxButton.YesNo) == MessageBoxResult.Yes) MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{ {
FilesFolders.OpenLocationInExporer(Constant.RootDirectory); FilesFolders.OpenPath(Constant.RootDirectory);
Environment.Exit(0); Environment.Exit(0);
} }

View file

@ -11,6 +11,7 @@
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -52,10 +53,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FSharp.Core" Version="4.7.1" />
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" /> <PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="squirrel.windows" Version="1.5.2" /> <PackageReference Include="squirrel.windows" Version="1.5.2" />
<PackageReference Include="PropertyChanged.Fody" Version="2.2.4"> <PackageReference Include="PropertyChanged.Fody" Version="3.2.8">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>

View file

@ -86,7 +86,7 @@ namespace Flow.Launcher.Core.Plugin
"Restart Flow Launcher to take effect?", "Restart Flow Launcher to take effect?",
"Install plugin", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) "Install plugin", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{ {
PluginManager.API.RestarApp(); PluginManager.API.RestartApp();
} }
} }
} }

View file

@ -20,21 +20,21 @@ namespace Flow.Launcher.Core.Plugin
public static List<PluginPair> Plugins(List<PluginMetadata> metadatas, PluginsSettings settings) public static List<PluginPair> Plugins(List<PluginMetadata> metadatas, PluginsSettings settings)
{ {
var csharpPlugins = CSharpPlugins(metadatas).ToList(); var dotnetPlugins = DotNetPlugins(metadatas).ToList();
var pythonPlugins = PythonPlugins(metadatas, settings.PythonDirectory); var pythonPlugins = PythonPlugins(metadatas, settings.PythonDirectory);
var executablePlugins = ExecutablePlugins(metadatas); var executablePlugins = ExecutablePlugins(metadatas);
var plugins = csharpPlugins.Concat(pythonPlugins).Concat(executablePlugins).ToList(); var plugins = dotnetPlugins.Concat(pythonPlugins).Concat(executablePlugins).ToList();
return plugins; return plugins;
} }
public static IEnumerable<PluginPair> CSharpPlugins(List<PluginMetadata> source) public static IEnumerable<PluginPair> DotNetPlugins(List<PluginMetadata> source)
{ {
var plugins = new List<PluginPair>(); var plugins = new List<PluginPair>();
var metadatas = source.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp); var metadatas = source.Where(o => AllowedLanguage.IsDotNet(o.Language));
foreach (var metadata in metadatas) foreach (var metadata in metadatas)
{ {
var milliseconds = Stopwatch.Debug($"|PluginsLoader.CSharpPlugins|Constructor init cost for {metadata.Name}", () => var milliseconds = Stopwatch.Debug($"|PluginsLoader.DotNetPlugins|Constructor init cost for {metadata.Name}", () =>
{ {
#if DEBUG #if DEBUG
@ -50,7 +50,7 @@ namespace Flow.Launcher.Core.Plugin
} }
catch (Exception e) catch (Exception e)
{ {
Log.Exception($"|PluginsLoader.CSharpPlugins|Couldn't load assembly for {metadata.Name}", e); Log.Exception($"|PluginsLoader.DotNetPlugins|Couldn't load assembly for {metadata.Name}", e);
return; return;
} }
var types = assembly.GetTypes(); var types = assembly.GetTypes();
@ -61,7 +61,7 @@ namespace Flow.Launcher.Core.Plugin
} }
catch (InvalidOperationException e) catch (InvalidOperationException e)
{ {
Log.Exception($"|PluginsLoader.CSharpPlugins|Can't find class implement IPlugin for <{metadata.Name}>", e); Log.Exception($"|PluginsLoader.DotNetPlugins|Can't find class implement IPlugin for <{metadata.Name}>", e);
return; return;
} }
IPlugin plugin; IPlugin plugin;
@ -71,7 +71,7 @@ namespace Flow.Launcher.Core.Plugin
} }
catch (Exception e) catch (Exception e)
{ {
Log.Exception($"|PluginsLoader.CSharpPlugins|Can't create instance for <{metadata.Name}>", e); Log.Exception($"|PluginsLoader.DotNetPlugins|Can't create instance for <{metadata.Name}>", e);
return; return;
} }
#endif #endif

View file

@ -13,11 +13,12 @@ namespace Flow.Launcher.Infrastructure.Image
{ {
public static class ImageLoader public static class ImageLoader
{ {
private static readonly ImageCache ImageCache = new ImageCache(); private static readonly ImageCache _imageCache = new ImageCache();
private static BinaryStorage<Dictionary<string, int>> _storage; private static readonly ConcurrentDictionary<string, string> _guidToKey = new ConcurrentDictionary<string, string>();
private static readonly ConcurrentDictionary<string, string> GuidToKey = new ConcurrentDictionary<string, string>(); private static readonly bool _enableHashImage = true;
private static IImageHashGenerator _hashGenerator;
private static BinaryStorage<Dictionary<string, int>> _storage;
private static IImageHashGenerator _hashGenerator;
private static readonly string[] ImageExtensions = private static readonly string[] ImageExtensions =
{ {
@ -30,30 +31,30 @@ namespace Flow.Launcher.Infrastructure.Image
".ico" ".ico"
}; };
public static void Initialize() public static void Initialize()
{ {
_storage = new BinaryStorage<Dictionary<string, int>>("Image"); _storage = new BinaryStorage<Dictionary<string, int>>("Image");
_hashGenerator = new ImageHashGenerator(); _hashGenerator = new ImageHashGenerator();
ImageCache.Usage = LoadStorageToConcurrentDictionary(); _imageCache.Usage = LoadStorageToConcurrentDictionary();
foreach (var icon in new[] { Constant.DefaultIcon, Constant.ErrorIcon }) foreach (var icon in new[] { Constant.DefaultIcon, Constant.ErrorIcon })
{ {
ImageSource img = new BitmapImage(new Uri(icon)); ImageSource img = new BitmapImage(new Uri(icon));
img.Freeze(); img.Freeze();
ImageCache[icon] = img; _imageCache[icon] = img;
} }
Task.Run(() => Task.Run(() =>
{ {
Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () => Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () =>
{ {
ImageCache.Usage.AsParallel().ForAll(x => _imageCache.Usage.AsParallel().ForAll(x =>
{ {
Load(x.Key); Load(x.Key);
}); });
}); });
Log.Info($"|ImageLoader.Initialize|Number of preload images is <{ImageCache.Usage.Count}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}"); Log.Info($"|ImageLoader.Initialize|Number of preload images is <{_imageCache.Usage.Count}>, Images Number: {_imageCache.CacheSize()}, Unique Items {_imageCache.UniqueImagesInCache()}");
}); });
} }
@ -61,7 +62,7 @@ namespace Flow.Launcher.Infrastructure.Image
{ {
lock (_storage) lock (_storage)
{ {
_storage.Save(ImageCache.CleanupAndToDictionary()); _storage.Save(_imageCache.CleanupAndToDictionary());
} }
} }
@ -99,17 +100,17 @@ namespace Flow.Launcher.Infrastructure.Image
private static ImageResult LoadInternal(string path, bool loadFullImage = false) private static ImageResult LoadInternal(string path, bool loadFullImage = false)
{ {
ImageSource image; ImageResult imageResult;
ImageType type = ImageType.Error;
try try
{ {
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))
{ {
return new ImageResult(ImageCache[Constant.ErrorIcon], ImageType.Error); return new ImageResult(_imageCache[Constant.ErrorIcon], ImageType.Error);
} }
if (ImageCache.ContainsKey(path)) if (_imageCache.ContainsKey(path))
{ {
return new ImageResult(ImageCache[path], ImageType.Cache); return new ImageResult(_imageCache[path], ImageType.Cache);
} }
if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
@ -124,69 +125,93 @@ namespace Flow.Launcher.Infrastructure.Image
path = Path.Combine(Constant.ProgramDirectory, "Images", Path.GetFileName(path)); path = Path.Combine(Constant.ProgramDirectory, "Images", Path.GetFileName(path));
} }
if (Directory.Exists(path)) imageResult = GetThumbnailResult(ref path, loadFullImage);
}
catch (System.Exception e)
{
try
{ {
/* Directories can also have thumbnails instead of shell icons. // Get thumbnail may fail for certain images on the first try, retry again has proven to work
* Generating thumbnails for a bunch of folders while scrolling through imageResult = GetThumbnailResult(ref path, loadFullImage);
* results from Everything makes a big impact on performance and
* Flow.Launcher responsibility.
* - Solution: just load the icon
*/
type = ImageType.Folder;
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize,
Constant.ThumbnailSize, ThumbnailOptions.IconOnly);
} }
else if (File.Exists(path)) catch (System.Exception e2)
{ {
var extension = Path.GetExtension(path).ToLower(); Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e);
if (ImageExtensions.Contains(extension)) Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2);
ImageSource image = _imageCache[Constant.ErrorIcon];
_imageCache[path] = image;
imageResult = new ImageResult(image, ImageType.Error);
}
}
return imageResult;
}
private static ImageResult GetThumbnailResult(ref string path, bool loadFullImage = false)
{
ImageSource image;
ImageType type = ImageType.Error;
if (Directory.Exists(path))
{
/* Directories can also have thumbnails instead of shell icons.
* Generating thumbnails for a bunch of folders while scrolling through
* results from Everything makes a big impact on performance and
* Flow.Launcher responsibility.
* - Solution: just load the icon
*/
type = ImageType.Folder;
image = GetThumbnail(path, ThumbnailOptions.IconOnly);
}
else if (File.Exists(path))
{
var extension = Path.GetExtension(path).ToLower();
if (ImageExtensions.Contains(extension))
{
type = ImageType.ImageFile;
if (loadFullImage)
{ {
type = ImageType.ImageFile; image = LoadFullImage(path);
if (loadFullImage)
{
image = LoadFullImage(path);
}
else
{
/* Although the documentation for GetImage on MSDN indicates that
* if a thumbnail is available it will return one, this has proved to not
* be the case in many situations while testing.
* - Solution: explicitly pass the ThumbnailOnly flag
*/
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize,
Constant.ThumbnailSize, ThumbnailOptions.ThumbnailOnly);
}
} }
else else
{ {
type = ImageType.File; /* Although the documentation for GetImage on MSDN indicates that
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, * if a thumbnail is available it will return one, this has proved to not
Constant.ThumbnailSize, ThumbnailOptions.None); * be the case in many situations while testing.
* - Solution: explicitly pass the ThumbnailOnly flag
*/
image = GetThumbnail(path, ThumbnailOptions.ThumbnailOnly);
} }
} }
else else
{ {
image = ImageCache[Constant.ErrorIcon]; type = ImageType.File;
path = Constant.ErrorIcon; image = GetThumbnail(path, ThumbnailOptions.None);
}
if (type != ImageType.Error)
{
image.Freeze();
} }
} }
catch (System.Exception e) else
{ {
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path}", e); image = _imageCache[Constant.ErrorIcon];
type = ImageType.Error; path = Constant.ErrorIcon;
image = ImageCache[Constant.ErrorIcon];
ImageCache[path] = image;
} }
if (type != ImageType.Error)
{
image.Freeze();
}
return new ImageResult(image, type); return new ImageResult(image, type);
} }
private static bool EnableImageHash = true; private static BitmapSource GetThumbnail(string path, ThumbnailOptions option = ThumbnailOptions.ThumbnailOnly)
{
return WindowsThumbnailProvider.GetThumbnail(
path,
Constant.ThumbnailSize,
Constant.ThumbnailSize,
option);
}
public static ImageSource Load(string path, bool loadFullImage = false) public static ImageSource Load(string path, bool loadFullImage = false)
{ {
@ -194,25 +219,27 @@ namespace Flow.Launcher.Infrastructure.Image
var img = imageResult.ImageSource; var img = imageResult.ImageSource;
if (imageResult.ImageType != ImageType.Error && imageResult.ImageType != ImageType.Cache) if (imageResult.ImageType != ImageType.Error && imageResult.ImageType != ImageType.Cache)
{ // we need to get image hash {
string hash = EnableImageHash ? _hashGenerator.GetHashFromImage(img) : null; // we need to get image hash
string hash = _enableHashImage ? _hashGenerator.GetHashFromImage(img) : null;
if (hash != null) if (hash != null)
{ {
if (GuidToKey.TryGetValue(hash, out string key)) if (_guidToKey.TryGetValue(hash, out string key))
{ // image already exists {
img = ImageCache[key]; // image already exists
img = _imageCache[key];
} }
else else
{ // new guid {
GuidToKey[hash] = path; // new guid
_guidToKey[hash] = path;
} }
} }
// update cache // update cache
ImageCache[path] = img; _imageCache[path] = img;
} }
return img; return img;
} }

View file

@ -0,0 +1,9 @@
namespace Flow.Launcher.Infrastructure
{
public static class KeyConstant
{
public const string Ctrl = nameof(Ctrl);
public const string Alt = nameof(Alt);
public const string Space = nameof(Space);
}
}

View file

@ -9,7 +9,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{ {
public class Settings : BaseModel public class Settings : BaseModel
{ {
public string Hotkey { get; set; } = "Alt + Space"; public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
public string OpenResultModifiers { get; set; } = KeyConstant.Alt;
public bool ShowOpenResultHotkey { get; set; } = true;
public string Language { get; set; } = "en"; public string Language { get; set; } = "en";
public string Theme { get; set; } = Constant.DefaultTheme; public string Theme { get; set; } = Constant.DefaultTheme;
public bool UseDropShadowEffect { get; set; } = false; public bool UseDropShadowEffect { get; set; } = false;

View file

@ -12,15 +12,26 @@
get { return "CSHARP"; } get { return "CSHARP"; }
} }
public static string FSharp
{
get { return "FSHARP"; }
}
public static string Executable public static string Executable
{ {
get { return "EXECUTABLE"; } get { return "EXECUTABLE"; }
} }
public static bool IsDotNet(string language)
{
return language.ToUpper() == CSharp
|| language.ToUpper() == FSharp;
}
public static bool IsAllowed(string language) public static bool IsAllowed(string language)
{ {
return language.ToUpper() == Python.ToUpper() return IsDotNet(language)
|| language.ToUpper() == CSharp.ToUpper() || language.ToUpper() == Python.ToUpper()
|| language.ToUpper() == Executable.ToUpper(); || language.ToUpper() == Executable.ToUpper();
} }
} }

View file

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
@ -55,7 +55,7 @@
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" /> <PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageReference Include="Mono.Cecil" Version="0.11.2" /> <PackageReference Include="Mono.Cecil" Version="0.11.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="PropertyChanged.Fody" Version="2.2.4"> <PackageReference Include="PropertyChanged.Fody" Version="3.2.8">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>

View file

@ -43,6 +43,12 @@ namespace Flow.Launcher.Plugin
/// <summary> /// <summary>
/// Restart Flow Launcher /// Restart Flow Launcher
/// </summary> /// </summary>
void RestartApp();
/// <summary>
/// Restart Flow Launcher
/// </summary>
[Obsolete("Use RestartApp instead. This method will be removed in Flow Launcher 1.3")]
void RestarApp(); void RestarApp();
/// <summary> /// <summary>

View file

@ -110,12 +110,12 @@ namespace Flow.Launcher.Plugin.SharedCommands
return File.Exists(filePath); return File.Exists(filePath);
} }
public static void OpenLocationInExporer(string location) public static void OpenPath(string fileOrFolderPath)
{ {
var psi = new ProcessStartInfo { FileName = FileExplorerProgramName, UseShellExecute = true, Arguments = location }; var psi = new ProcessStartInfo { FileName = FileExplorerProgramName, UseShellExecute = true, Arguments = fileOrFolderPath };
try try
{ {
if (LocationExists(location)) if (LocationExists(fileOrFolderPath) || FileExits(fileOrFolderPath))
Process.Start(psi); Process.Start(psi);
} }
catch (Exception e) catch (Exception e)
@ -123,7 +123,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
#if DEBUG #if DEBUG
throw e; throw e;
#else #else
MessageBox.Show(string.Format("Unable to open location {0}, please check if it exists", location)); MessageBox.Show(string.Format("Unable to open the path {0}, please check if it exists", fileOrFolderPath));
#endif #endif
} }
} }

View file

@ -10,6 +10,7 @@
<ApplicationIcon /> <ApplicationIcon />
<StartupObject /> <StartupObject />
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -46,10 +47,13 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Moq" Version="4.13.1" /> <PackageReference Include="Moq" Version="4.14.1" />
<PackageReference Include="nunit" Version="3.12.0" /> <PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" /> <PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" /> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -74,6 +74,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Browse
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Calculator", "Plugins\Flow.Launcher.Plugin.Calculator\Flow.Launcher.Plugin.Calculator.csproj", "{59BD9891-3837-438A-958D-ADC7F91F6F7E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Calculator", "Plugins\Flow.Launcher.Plugin.Calculator\Flow.Launcher.Plugin.Calculator.csproj", "{59BD9891-3837-438A-958D-ADC7F91F6F7E}"
EndProject EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "HelloWorldFSharp", "Plugins\HelloWorldFSharp\HelloWorldFSharp.fsproj", "{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -313,6 +315,18 @@ Global
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x64.Build.0 = Release|Any CPU {59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x64.Build.0 = Release|Any CPU
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x86.ActiveCfg = Release|Any CPU {59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x86.ActiveCfg = Release|Any CPU
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x86.Build.0 = Release|Any CPU {59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x86.Build.0 = Release|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x64.ActiveCfg = Debug|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x64.Build.0 = Debug|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x86.ActiveCfg = Debug|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x86.Build.0 = Debug|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|Any CPU.Build.0 = Release|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x64.ActiveCfg = Release|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x64.Build.0 = Release|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x86.ActiveCfg = Release|Any CPU
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -332,6 +346,7 @@ Global
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{9B130CC5-14FB-41FF-B310-0A95B6894C37} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {9B130CC5-14FB-41FF-B310-0A95B6894C37} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{59BD9891-3837-438A-958D-ADC7F91F6F7E} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {59BD9891-3837-438A-958D-ADC7F91F6F7E} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F26ACB50-3F6C-4907-B0C9-1ADACC1D0DED} SolutionGuid = {F26ACB50-3F6C-4907-B0C9-1ADACC1D0DED}

View file

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace Flow.Launcher.Converters
{
[ValueConversion(typeof(bool), typeof(Visibility))]
public class OpenResultHotkeyVisibilityConverter : IValueConverter
{
private const int MaxVisibleHotkeys = 9;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var hotkeyNumber = int.MaxValue;
if (value is ListBoxItem listBoxItem)
{
ListBox listBox = ItemsControl.ItemsControlFromItemContainer(listBoxItem) as ListBox;
hotkeyNumber = listBox.ItemContainerGenerator.IndexFromContainer(listBoxItem) + 1;
}
return hotkeyNumber <= MaxVisibleHotkeys ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new System.InvalidOperationException();
}
}

View file

@ -0,0 +1,22 @@
using System.Globalization;
using System.Windows.Controls;
using System.Windows.Data;
namespace Flow.Launcher.Converters
{
public class OrdinalConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, CultureInfo culture)
{
if (value is ListBoxItem listBoxItem)
{
ListBox listBox = ItemsControl.ItemsControlFromItemContainer(listBoxItem) as ListBox;
return listBox.ItemContainerGenerator.IndexFromContainer(listBoxItem) + 1;
}
return 0;
}
public object ConvertBack(object value, System.Type targetType, object parameter, CultureInfo culture) => throw new System.InvalidOperationException();
}
}

View file

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
@ -11,6 +11,7 @@
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@ -65,7 +66,7 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="PropertyChanged.Fody" Version="2.2.4"> <PackageReference Include="PropertyChanged.Fody" Version="3.2.8">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>

View file

@ -50,7 +50,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Genvejstast</system:String> <system:String x:Key="hotkey">Genvejstast</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher genvejstast</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher genvejstast</system:String>
<system:String x:Key="openResultModifiers">Åbn resultatmodifikatorer</system:String>
<system:String x:Key="customQueryHotkey">Tilpasset søgegenvejstast</system:String> <system:String x:Key="customQueryHotkey">Tilpasset søgegenvejstast</system:String>
<system:String x:Key="showOpenResultHotkey">Vis hotkey</system:String>
<system:String x:Key="delete">Slet</system:String> <system:String x:Key="delete">Slet</system:String>
<system:String x:Key="edit">Rediger</system:String> <system:String x:Key="edit">Rediger</system:String>
<system:String x:Key="add">Tilføj</system:String> <system:String x:Key="add">Tilføj</system:String>

View file

@ -50,7 +50,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Tastenkombination</system:String> <system:String x:Key="hotkey">Tastenkombination</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher Tastenkombination</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher Tastenkombination</system:String>
<system:String x:Key="openResultModifiers">Öffnen Sie die Ergebnismodifikatoren</system:String>
<system:String x:Key="customQueryHotkey">Benutzerdefinierte Abfrage Tastenkombination</system:String> <system:String x:Key="customQueryHotkey">Benutzerdefinierte Abfrage Tastenkombination</system:String>
<system:String x:Key="showOpenResultHotkey">Hotkey anzeigen</system:String>
<system:String x:Key="delete">Löschen</system:String> <system:String x:Key="delete">Löschen</system:String>
<system:String x:Key="edit">Bearbeiten</system:String> <system:String x:Key="edit">Bearbeiten</system:String>
<system:String x:Key="add">Hinzufügen</system:String> <system:String x:Key="add">Hinzufügen</system:String>

View file

@ -60,6 +60,8 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Hotkey</system:String> <system:String x:Key="hotkey">Hotkey</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher Hotkey</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher Hotkey</system:String>
<system:String x:Key="openResultModifiers">Open Result Modifiers</system:String>
<system:String x:Key="showOpenResultHotkey">Show Hotkey</system:String>
<system:String x:Key="customQueryHotkey">Custom Query Hotkey</system:String> <system:String x:Key="customQueryHotkey">Custom Query Hotkey</system:String>
<system:String x:Key="delete">Delete</system:String> <system:String x:Key="delete">Delete</system:String>
<system:String x:Key="edit">Edit</system:String> <system:String x:Key="edit">Edit</system:String>

View file

@ -54,7 +54,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Raccourcis</system:String> <system:String x:Key="hotkey">Raccourcis</system:String>
<system:String x:Key="flowlauncherHotkey">Ouvrir Flow Launcher</system:String> <system:String x:Key="flowlauncherHotkey">Ouvrir Flow Launcher</system:String>
<system:String x:Key="openResultModifiers">Modificateurs de résultats ouverts</system:String>
<system:String x:Key="customQueryHotkey">Requêtes personnalisées</system:String> <system:String x:Key="customQueryHotkey">Requêtes personnalisées</system:String>
<system:String x:Key="showOpenResultHotkey">Afficher le raccourci clavier</system:String>
<system:String x:Key="delete">Supprimer</system:String> <system:String x:Key="delete">Supprimer</system:String>
<system:String x:Key="edit">Modifier</system:String> <system:String x:Key="edit">Modifier</system:String>
<system:String x:Key="add">Ajouter</system:String> <system:String x:Key="add">Ajouter</system:String>

View file

@ -54,7 +54,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Tasti scelta rapida</system:String> <system:String x:Key="hotkey">Tasti scelta rapida</system:String>
<system:String x:Key="flowlauncherHotkey">Tasto scelta rapida Flow Launcher</system:String> <system:String x:Key="flowlauncherHotkey">Tasto scelta rapida Flow Launcher</system:String>
<system:String x:Key="openResultModifiers">Apri modificatori di risultato</system:String>
<system:String x:Key="customQueryHotkey">Tasti scelta rapida per ricerche personalizzate</system:String> <system:String x:Key="customQueryHotkey">Tasti scelta rapida per ricerche personalizzate</system:String>
<system:String x:Key="showOpenResultHotkey">Mostra tasto di scelta rapida</system:String>
<system:String x:Key="delete">Cancella</system:String> <system:String x:Key="delete">Cancella</system:String>
<system:String x:Key="edit">Modifica</system:String> <system:String x:Key="edit">Modifica</system:String>
<system:String x:Key="add">Aggiungi</system:String> <system:String x:Key="add">Aggiungi</system:String>

View file

@ -57,7 +57,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">ホットキー</system:String> <system:String x:Key="hotkey">ホットキー</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher ホットキー</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher ホットキー</system:String>
<system:String x:Key="openResultModifiers">結果修飾子を開く</system:String>
<system:String x:Key="customQueryHotkey">カスタムクエリ ホットキー</system:String> <system:String x:Key="customQueryHotkey">カスタムクエリ ホットキー</system:String>
<system:String x:Key="showOpenResultHotkey">ホットキーを表示</system:String>
<system:String x:Key="delete">削除</system:String> <system:String x:Key="delete">削除</system:String>
<system:String x:Key="edit">編集</system:String> <system:String x:Key="edit">編集</system:String>
<system:String x:Key="add">追加</system:String> <system:String x:Key="add">追加</system:String>

View file

@ -54,7 +54,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">핫키</system:String> <system:String x:Key="hotkey">핫키</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher 핫키</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher 핫키</system:String>
<system:String x:Key="openResultModifiers">결과 수정 자 열기</system:String>
<system:String x:Key="customQueryHotkey">사용자지정 쿼리 핫키</system:String> <system:String x:Key="customQueryHotkey">사용자지정 쿼리 핫키</system:String>
<system:String x:Key="showOpenResultHotkey">단축키 표시</system:String>
<system:String x:Key="delete">삭제</system:String> <system:String x:Key="delete">삭제</system:String>
<system:String x:Key="edit">편집</system:String> <system:String x:Key="edit">편집</system:String>
<system:String x:Key="add">추가</system:String> <system:String x:Key="add">추가</system:String>

View file

@ -54,7 +54,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Hurtigtast</system:String> <system:String x:Key="hotkey">Hurtigtast</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher-hurtigtast</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher-hurtigtast</system:String>
<system:String x:Key="openResultModifiers">Åpne resultatmodifiserere</system:String>
<system:String x:Key="customQueryHotkey">Egendefinerd spørringshurtigtast</system:String> <system:String x:Key="customQueryHotkey">Egendefinerd spørringshurtigtast</system:String>
<system:String x:Key="showOpenResultHotkey">Vis hurtigtast</system:String>
<system:String x:Key="delete">Slett</system:String> <system:String x:Key="delete">Slett</system:String>
<system:String x:Key="edit">Rediger</system:String> <system:String x:Key="edit">Rediger</system:String>
<system:String x:Key="add">Legg til</system:String> <system:String x:Key="add">Legg til</system:String>

View file

@ -50,7 +50,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Sneltoets</system:String> <system:String x:Key="hotkey">Sneltoets</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher Sneltoets</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher Sneltoets</system:String>
<system:String x:Key="openResultModifiers">Open resultaatmodificatoren</system:String>
<system:String x:Key="customQueryHotkey">Custom Query Sneltoets</system:String> <system:String x:Key="customQueryHotkey">Custom Query Sneltoets</system:String>
<system:String x:Key="showOpenResultHotkey">Sneltoets weergeven</system:String>
<system:String x:Key="delete">Verwijder</system:String> <system:String x:Key="delete">Verwijder</system:String>
<system:String x:Key="edit">Bewerken</system:String> <system:String x:Key="edit">Bewerken</system:String>
<system:String x:Key="add">Toevoegen</system:String> <system:String x:Key="add">Toevoegen</system:String>

View file

@ -50,7 +50,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Skrót klawiszowy</system:String> <system:String x:Key="hotkey">Skrót klawiszowy</system:String>
<system:String x:Key="flowlauncherHotkey">Skrót klawiszowy Flow Launcher</system:String> <system:String x:Key="flowlauncherHotkey">Skrót klawiszowy Flow Launcher</system:String>
<system:String x:Key="openResultModifiers">Modyfikatory klawiszów otwierających wyniki</system:String>
<system:String x:Key="customQueryHotkey">Skrót klawiszowy niestandardowych zapytań</system:String> <system:String x:Key="customQueryHotkey">Skrót klawiszowy niestandardowych zapytań</system:String>
<system:String x:Key="showOpenResultHotkey">Pokaż skrót klawiszowy</system:String>
<system:String x:Key="delete">Usuń</system:String> <system:String x:Key="delete">Usuń</system:String>
<system:String x:Key="edit">Edytuj</system:String> <system:String x:Key="edit">Edytuj</system:String>
<system:String x:Key="add">Dodaj</system:String> <system:String x:Key="add">Dodaj</system:String>

View file

@ -54,7 +54,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Atalho</system:String> <system:String x:Key="hotkey">Atalho</system:String>
<system:String x:Key="flowlauncherHotkey">Atalho do Flow Launcher</system:String> <system:String x:Key="flowlauncherHotkey">Atalho do Flow Launcher</system:String>
<system:String x:Key="openResultModifiers">Modificadores de resultado aberto</system:String>
<system:String x:Key="customQueryHotkey">Atalho de Consulta Personalizada</system:String> <system:String x:Key="customQueryHotkey">Atalho de Consulta Personalizada</system:String>
<system:String x:Key="showOpenResultHotkey">Mostrar tecla de atalho</system:String>
<system:String x:Key="delete">Apagar</system:String> <system:String x:Key="delete">Apagar</system:String>
<system:String x:Key="edit">Editar</system:String> <system:String x:Key="edit">Editar</system:String>
<system:String x:Key="add">Adicionar</system:String> <system:String x:Key="add">Adicionar</system:String>

View file

@ -50,7 +50,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Горячие клавиши</system:String> <system:String x:Key="hotkey">Горячие клавиши</system:String>
<system:String x:Key="flowlauncherHotkey">Горячая клавиша Flow Launcher</system:String> <system:String x:Key="flowlauncherHotkey">Горячая клавиша Flow Launcher</system:String>
<system:String x:Key="openResultModifiers">Модификаторы открытого результата</system:String>
<system:String x:Key="customQueryHotkey">Задаваемые горячие клавиши для запросов</system:String> <system:String x:Key="customQueryHotkey">Задаваемые горячие клавиши для запросов</system:String>
<system:String x:Key="showOpenResultHotkey">Показать Hotkey</system:String>
<system:String x:Key="delete">Удалить</system:String> <system:String x:Key="delete">Удалить</system:String>
<system:String x:Key="edit">Изменить</system:String> <system:String x:Key="edit">Изменить</system:String>
<system:String x:Key="add">Добавить</system:String> <system:String x:Key="add">Добавить</system:String>

View file

@ -55,7 +55,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Klávesová skratka</system:String> <system:String x:Key="hotkey">Klávesová skratka</system:String>
<system:String x:Key="flowlauncherHotkey">Klávesová skratka pre Flow Launcher</system:String> <system:String x:Key="flowlauncherHotkey">Klávesová skratka pre Flow Launcher</system:String>
<system:String x:Key="openResultModifiers">Otvorte modifikátory výsledkov</system:String>
<system:String x:Key="customQueryHotkey">Vlastná klávesová skratka pre dopyt</system:String> <system:String x:Key="customQueryHotkey">Vlastná klávesová skratka pre dopyt</system:String>
<system:String x:Key="showOpenResultHotkey">Zobraziť klávesovú skratku</system:String>
<system:String x:Key="delete">Odstrániť</system:String> <system:String x:Key="delete">Odstrániť</system:String>
<system:String x:Key="edit">Upraviť</system:String> <system:String x:Key="edit">Upraviť</system:String>
<system:String x:Key="add">Pridať</system:String> <system:String x:Key="add">Pridať</system:String>

View file

@ -54,6 +54,8 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Prečica</system:String> <system:String x:Key="hotkey">Prečica</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher prečica</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher prečica</system:String>
<system:String x:Key="openResultModifiers">Отворите модификаторе резултата</system:String>
<system:String x:Key="showOpenResultHotkey">покажи хоткеи</system:String>
<system:String x:Key="customQueryHotkey">prečica za ručno dodat upit</system:String> <system:String x:Key="customQueryHotkey">prečica za ručno dodat upit</system:String>
<system:String x:Key="delete">Obriši</system:String> <system:String x:Key="delete">Obriši</system:String>
<system:String x:Key="edit">Izmeni</system:String> <system:String x:Key="edit">Izmeni</system:String>

View file

@ -58,7 +58,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Kısayol Tuşu</system:String> <system:String x:Key="hotkey">Kısayol Tuşu</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher Kısayolu</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher Kısayolu</system:String>
<system:String x:Key="openResultModifiers">Açık Sonuç Değiştiricileri</system:String>
<system:String x:Key="customQueryHotkey">Özel Sorgu Kısayolları</system:String> <system:String x:Key="customQueryHotkey">Özel Sorgu Kısayolları</system:String>
<system:String x:Key="showOpenResultHotkey">Kısayol Tuşunu Göster</system:String>
<system:String x:Key="delete">Sil</system:String> <system:String x:Key="delete">Sil</system:String>
<system:String x:Key="edit">Düzenle</system:String> <system:String x:Key="edit">Düzenle</system:String>
<system:String x:Key="add">Ekle</system:String> <system:String x:Key="add">Ekle</system:String>

View file

@ -50,7 +50,9 @@
<!--Setting Hotkey--> <!--Setting Hotkey-->
<system:String x:Key="hotkey">Гарячі клавіші</system:String> <system:String x:Key="hotkey">Гарячі клавіші</system:String>
<system:String x:Key="flowlauncherHotkey">Гаряча клавіша Flow Launcher</system:String> <system:String x:Key="flowlauncherHotkey">Гаряча клавіша Flow Launcher</system:String>
<system:String x:Key="openResultModifiers">Відкриті модифікатори результатів</system:String>
<system:String x:Key="customQueryHotkey">Задані гарячі клавіші для запитів</system:String> <system:String x:Key="customQueryHotkey">Задані гарячі клавіші для запитів</system:String>
<system:String x:Key="showOpenResultHotkey">Показати клавішу швидкого доступу</system:String>
<system:String x:Key="delete">Видалити</system:String> <system:String x:Key="delete">Видалити</system:String>
<system:String x:Key="edit">Змінити</system:String> <system:String x:Key="edit">Змінити</system:String>
<system:String x:Key="add">Додати</system:String> <system:String x:Key="add">Додати</system:String>

View file

@ -57,6 +57,8 @@
<!--设置,热键--> <!--设置,热键-->
<system:String x:Key="hotkey">热键</system:String> <system:String x:Key="hotkey">热键</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher激活热键</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher激活热键</system:String>
<system:String x:Key="openResultModifiers">开放结果修饰符</system:String>
<system:String x:Key="showOpenResultHotkey">显示热键</system:String>
<system:String x:Key="customQueryHotkey">自定义查询热键</system:String> <system:String x:Key="customQueryHotkey">自定义查询热键</system:String>
<system:String x:Key="delete">删除</system:String> <system:String x:Key="delete">删除</system:String>
<system:String x:Key="edit">编辑</system:String> <system:String x:Key="edit">编辑</system:String>

View file

@ -50,7 +50,9 @@
<!--設置,熱鍵--> <!--設置,熱鍵-->
<system:String x:Key="hotkey">熱鍵</system:String> <system:String x:Key="hotkey">熱鍵</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher 執行熱鍵</system:String> <system:String x:Key="flowlauncherHotkey">Flow Launcher 執行熱鍵</system:String>
<system:String x:Key="openResultModifiers">開放結果修飾符</system:String>
<system:String x:Key="customQueryHotkey">自定義熱鍵查詢</system:String> <system:String x:Key="customQueryHotkey">自定義熱鍵查詢</system:String>
<system:String x:Key="showOpenResultHotkey">顯示熱鍵</system:String>
<system:String x:Key="delete">刪除</system:String> <system:String x:Key="delete">刪除</system:String>
<system:String x:Key="edit">編輯</system:String> <system:String x:Key="edit">編輯</system:String>
<system:String x:Key="add">新增</system:String> <system:String x:Key="add">新增</system:String>

View file

@ -49,15 +49,15 @@
<KeyBinding Key="Enter" Command="{Binding OpenResultCommand}"></KeyBinding> <KeyBinding Key="Enter" Command="{Binding OpenResultCommand}"></KeyBinding>
<KeyBinding Key="Enter" Modifiers="Ctrl" Command="{Binding OpenResultCommand}"></KeyBinding> <KeyBinding Key="Enter" Modifiers="Ctrl" Command="{Binding OpenResultCommand}"></KeyBinding>
<KeyBinding Key="Enter" Modifiers="Alt" Command="{Binding OpenResultCommand}"></KeyBinding> <KeyBinding Key="Enter" Modifiers="Alt" Command="{Binding OpenResultCommand}"></KeyBinding>
<KeyBinding Key="D1" Modifiers="Alt" Command="{Binding OpenResultCommand}" CommandParameter="0"></KeyBinding> <KeyBinding Key="D1" Modifiers="{Binding OpenResultCommandModifiers}" Command="{Binding OpenResultCommand}" CommandParameter="0"></KeyBinding>
<KeyBinding Key="D2" Modifiers="Alt" Command="{Binding OpenResultCommand}" CommandParameter="1"></KeyBinding> <KeyBinding Key="D2" Modifiers="{Binding OpenResultCommandModifiers}" Command="{Binding OpenResultCommand}" CommandParameter="1"></KeyBinding>
<KeyBinding Key="D3" Modifiers="Alt" Command="{Binding OpenResultCommand}" CommandParameter="2"></KeyBinding> <KeyBinding Key="D3" Modifiers="{Binding OpenResultCommandModifiers}" Command="{Binding OpenResultCommand}" CommandParameter="2"></KeyBinding>
<KeyBinding Key="D4" Modifiers="Alt" Command="{Binding OpenResultCommand}" CommandParameter="3"></KeyBinding> <KeyBinding Key="D4" Modifiers="{Binding OpenResultCommandModifiers}" Command="{Binding OpenResultCommand}" CommandParameter="3"></KeyBinding>
<KeyBinding Key="D5" Modifiers="Alt" Command="{Binding OpenResultCommand}" CommandParameter="4"></KeyBinding> <KeyBinding Key="D5" Modifiers="{Binding OpenResultCommandModifiers}" Command="{Binding OpenResultCommand}" CommandParameter="4"></KeyBinding>
<KeyBinding Key="D6" Modifiers="Alt" Command="{Binding OpenResultCommand}" CommandParameter="5"></KeyBinding> <KeyBinding Key="D6" Modifiers="{Binding OpenResultCommandModifiers}" Command="{Binding OpenResultCommand}" CommandParameter="5"></KeyBinding>
<KeyBinding Key="D7" Modifiers="Alt" Command="{Binding OpenResultCommand}" CommandParameter="6"></KeyBinding> <KeyBinding Key="D7" Modifiers="{Binding OpenResultCommandModifiers}" Command="{Binding OpenResultCommand}" CommandParameter="6"></KeyBinding>
<KeyBinding Key="D8" Modifiers="Alt" Command="{Binding OpenResultCommand}" CommandParameter="7"></KeyBinding> <KeyBinding Key="D8" Modifiers="{Binding OpenResultCommandModifiers}" Command="{Binding OpenResultCommand}" CommandParameter="7"></KeyBinding>
<KeyBinding Key="D9" Modifiers="Alt" Command="{Binding OpenResultCommand}" CommandParameter="8"></KeyBinding> <KeyBinding Key="D9" Modifiers="{Binding OpenResultCommandModifiers}" Command="{Binding OpenResultCommand}" CommandParameter="8"></KeyBinding>
</Window.InputBindings> </Window.InputBindings>
<Grid Width="750"> <Grid Width="750">
<Border Style="{DynamicResource WindowBorderStyle}" MouseDown="OnMouseDown" CornerRadius="5" > <Border Style="{DynamicResource WindowBorderStyle}" MouseDown="OnMouseDown" CornerRadius="5" >

View file

@ -54,7 +54,7 @@ namespace Flow.Launcher
Application.Current.MainWindow.Close(); Application.Current.MainWindow.Close();
} }
public void RestarApp() public void RestartApp()
{ {
_mainVM.MainWindowVisibility = Visibility.Hidden; _mainVM.MainWindowVisibility = Visibility.Hidden;
@ -66,6 +66,11 @@ namespace Flow.Launcher
UpdateManager.RestartApp(Constant.ApplicationFileName); UpdateManager.RestartApp(Constant.ApplicationFileName);
} }
public void RestarApp()
{
RestartApp();
}
public void CheckForNewUpdate() public void CheckForNewUpdate()
{ {
_settingsVM.UpdateApp(); _settingsVM.UpdateApp();

View file

@ -33,6 +33,8 @@
Cursor="Hand" UseLayoutRounding="False"> Cursor="Hand" UseLayoutRounding="False">
<Grid.Resources> <Grid.Resources>
<converter:HighlightTextConverter x:Key="HighlightTextConverter"/> <converter:HighlightTextConverter x:Key="HighlightTextConverter"/>
<converter:OrdinalConverter x:Key="OrdinalConverter" />
<converter:OpenResultHotkeyVisibilityConverter x:Key="OpenResultHotkeyVisibilityConverter" />
</Grid.Resources> </Grid.Resources>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="32" /> <ColumnDefinition Width="32" />
@ -46,6 +48,19 @@
<RowDefinition /> <RowDefinition />
<RowDefinition Height="Auto" x:Name="SubTitleRowDefinition" /> <RowDefinition Height="Auto" x:Name="SubTitleRowDefinition" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel Visibility="{Binding ShowOpenResultHotkey}">
<TextBlock Margin="0 5 5 0" Style="{DynamicResource ItemSubTitleStyle}" HorizontalAlignment="Right" Opacity="0.8" >
<TextBlock.Visibility>
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}" Converter="{StaticResource ResourceKey=OpenResultHotkeyVisibilityConverter}" />
</TextBlock.Visibility>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}+{1}">
<Binding Path="OpenResultModifiers" />
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}" Converter="{StaticResource ResourceKey=OrdinalConverter}" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
<TextBlock Style="{DynamicResource ItemTitleStyle}" DockPanel.Dock="Left" <TextBlock Style="{DynamicResource ItemTitleStyle}" DockPanel.Dock="Left"
VerticalAlignment="Center" ToolTip="{Binding Result.Title}" x:Name="Title" VerticalAlignment="Center" ToolTip="{Binding Result.Title}" x:Name="Title"
Text="{Binding Result.Title}"> Text="{Binding Result.Title}">

View file

@ -312,8 +312,9 @@
<Grid Margin="30 10 30 10"> <Grid Margin="30 10 30 10">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="80" /> <RowDefinition Height="80" />
<RowDefinition Height="25" /> <RowDefinition Height="35" />
<RowDefinition Height="340" /> <RowDefinition Height="70" />
<RowDefinition Height="250" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" VerticalAlignment="Center" <StackPanel Grid.Row="0" Orientation="Horizontal" VerticalAlignment="Center"
@ -322,13 +323,22 @@
<flowlauncher:HotkeyControl x:Name="HotkeyControl" HotkeyChanged="OnHotkeyChanged" <flowlauncher:HotkeyControl x:Name="HotkeyControl" HotkeyChanged="OnHotkeyChanged"
Loaded="OnHotkeyControlLoaded" Height="35"/> Loaded="OnHotkeyControlLoaded" Height="35"/>
</StackPanel> </StackPanel>
<TextBlock VerticalAlignment="Center" Grid.Row="1" Margin="0,3,10,2" <StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center"
Text="{DynamicResource customQueryHotkey}" FontSize="14" /> Margin="0,4,0,3">
<ListView ItemsSource="{Binding Settings.CustomPluginHotkeys}" <TextBlock VerticalAlignment="Center" Margin="0 0 10 0" Text="{DynamicResource openResultModifiers}" FontSize="14" />
<ComboBox Margin="0 0 0 0" Width="120"
ItemsSource="{Binding OpenResultModifiersList}"
SelectedItem="{Binding Settings.OpenResultModifiers}" FontSize="14" />
<CheckBox Margin="30 0 0 0" IsChecked="{Binding Settings.ShowOpenResultHotkey}" VerticalAlignment="Center">
<TextBlock Text="{DynamicResource showOpenResultHotkey}" FontSize="14" />
</CheckBox>
</StackPanel>
<TextBlock Grid.Row="2" VerticalAlignment="Center" Margin="0 23 10 2" Text="{DynamicResource customQueryHotkey}" FontSize="14" />
<ListView Grid.Row="3" ItemsSource="{Binding Settings.CustomPluginHotkeys}"
SelectedItem="{Binding SelectedCustomPluginHotkey}" SelectedItem="{Binding SelectedCustomPluginHotkey}"
Style="{StaticResource {x:Static GridView.GridViewStyleKey}}" Style="{StaticResource {x:Static GridView.GridViewStyleKey}}"
BorderBrush="DarkGray" BorderThickness="1" BorderBrush="DarkGray" BorderThickness="1"
Margin="0 5 0 0" Grid.Row="2"> Margin="0 5 0 0">
<ListView.View> <ListView.View>
<GridView> <GridView>
<GridViewColumn Header="{DynamicResource hotkey}" Width="180"> <GridViewColumn Header="{DynamicResource hotkey}" Width="180">
@ -338,7 +348,7 @@
</DataTemplate> </DataTemplate>
</GridViewColumn.CellTemplate> </GridViewColumn.CellTemplate>
</GridViewColumn> </GridViewColumn>
<GridViewColumn Header="{DynamicResource actionKeywords}" Width="500"> <GridViewColumn Header="{DynamicResource actionKeywords}" Width="546">
<GridViewColumn.CellTemplate> <GridViewColumn.CellTemplate>
<DataTemplate DataType="userSettings:CustomPluginHotkey"> <DataTemplate DataType="userSettings:CustomPluginHotkey">
<TextBlock Text="{Binding ActionKeyword}" /> <TextBlock Text="{Binding ActionKeyword}" />
@ -348,7 +358,7 @@
</GridView> </GridView>
</ListView.View> </ListView.View>
</ListView> </ListView>
<StackPanel Grid.Row="3" HorizontalAlignment="Right" VerticalAlignment="Bottom" <StackPanel Grid.Row="4" HorizontalAlignment="Right" VerticalAlignment="Bottom"
Orientation="Horizontal" Width="360"> Orientation="Horizontal" Width="360">
<Button Click="OnDeleteCustomHotkeyClick" Width="100" <Button Click="OnDeleteCustomHotkeyClick" Width="100"
Margin="10" Content="{DynamicResource delete}" /> Margin="10" Content="{DynamicResource delete}" />

View file

@ -241,7 +241,7 @@ namespace Flow.Launcher
{ {
var directory = _viewModel.SelectedPlugin.PluginPair.Metadata.PluginDirectory; var directory = _viewModel.SelectedPlugin.PluginPair.Metadata.PluginDirectory;
if (!string.IsNullOrEmpty(directory)) if (!string.IsNullOrEmpty(directory))
FilesFolders.OpenLocationInExporer(directory); FilesFolders.OpenPath(directory);
} }
} }
#endregion #endregion

View file

@ -28,6 +28,8 @@ namespace Flow.Launcher.ViewModel
{ {
#region Private Fields #region Private Fields
private const string DefaultOpenResultModifiers = "Alt";
private bool _isQueryRunning; private bool _isQueryRunning;
private Query _lastQuery; private Query _lastQuery;
private string _queryTextBeforeLeaveResults; private string _queryTextBeforeLeaveResults;
@ -76,6 +78,7 @@ namespace Flow.Launcher.ViewModel
SetHotkey(_settings.Hotkey, OnHotkey); SetHotkey(_settings.Hotkey, OnHotkey);
SetCustomPluginHotkey(); SetCustomPluginHotkey();
SetOpenResultModifiers();
} }
private void RegisterResultsUpdatedEvent() private void RegisterResultsUpdatedEvent()
@ -279,6 +282,8 @@ namespace Flow.Launcher.ViewModel
public ICommand LoadHistoryCommand { get; set; } public ICommand LoadHistoryCommand { get; set; }
public ICommand OpenResultCommand { get; set; } public ICommand OpenResultCommand { get; set; }
public string OpenResultCommandModifiers { get; private set; }
public ImageSource Image => ImageLoader.Load(Constant.QueryTextBoxIconImagePath); public ImageSource Image => ImageLoader.Load(Constant.QueryTextBoxIconImagePath);
#endregion #endregion
@ -598,6 +603,11 @@ namespace Flow.Launcher.ViewModel
} }
} }
private void SetOpenResultModifiers()
{
OpenResultCommandModifiers = _settings.OpenResultModifiers ?? DefaultOpenResultModifiers;
}
private void OnHotkey(object sender, HotkeyEventArgs e) private void OnHotkey(object sender, HotkeyEventArgs e)
{ {
if (!ShouldIgnoreHotkeys()) if (!ShouldIgnoreHotkeys())

View file

@ -1,9 +1,11 @@
using System; using System;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading; using System.Windows.Threading;
using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Image; using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin; using Flow.Launcher.Plugin;
@ -11,14 +13,22 @@ namespace Flow.Launcher.ViewModel
{ {
public class ResultViewModel : BaseModel public class ResultViewModel : BaseModel
{ {
public ResultViewModel(Result result) public ResultViewModel(Result result, Settings settings)
{ {
if (result != null) if (result != null)
{ {
Result = result; Result = result;
} }
Settings = settings;
} }
public Settings Settings { get; private set; }
public Visibility ShowOpenResultHotkey => Settings.ShowOpenResultHotkey ? Visibility.Visible : Visibility.Hidden;
public string OpenResultModifiers => Settings.OpenResultModifiers;
public ImageSource Image public ImageSource Image
{ {
get get

View file

@ -156,7 +156,7 @@ namespace Flow.Launcher.ViewModel
private List<ResultViewModel> NewResults(List<Result> newRawResults, string resultId) private List<ResultViewModel> NewResults(List<Result> newRawResults, string resultId)
{ {
var results = Results.ToList(); var results = Results.ToList();
var newResults = newRawResults.Select(r => new ResultViewModel(r)).ToList(); var newResults = newRawResults.Select(r => new ResultViewModel(r, _settings)).ToList();
var oldResults = results.Where(r => r.Result.PluginID == resultId).ToList(); var oldResults = results.Where(r => r.Result.PluginID == resultId).ToList();
// Find the same results in A (old results) and B (new newResults) // Find the same results in A (old results) and B (new newResults)

View file

@ -160,6 +160,7 @@ namespace Flow.Launcher.ViewModel
} }
} }
public List<string> OpenResultModifiersList => new List<string> { KeyConstant.Alt, KeyConstant.Ctrl, $"{KeyConstant.Ctrl}+{KeyConstant.Alt}" };
private Internationalization _translater => InternationalizationManager.Instance; private Internationalization _translater => InternationalizationManager.Instance;
public List<Language> Languages => _translater.LoadAvailableLanguages(); public List<Language> Languages => _translater.LoadAvailableLanguages();
public IEnumerable<int> MaxResultsRange => Enumerable.Range(2, 16); public IEnumerable<int> MaxResultsRange => Enumerable.Range(2, 16);

View file

@ -89,7 +89,7 @@ namespace Flow.Launcher.Plugin.Folder
if (record.Type == ResultType.File) if (record.Type == ResultType.File)
File.Delete(record.FullPath); File.Delete(record.FullPath);
else else
Directory.Delete(record.FullPath); Directory.Delete(record.FullPath, true);
} }
catch(Exception e) catch(Exception e)
{ {

View file

@ -1,6 +1,6 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
@ -27,6 +27,8 @@ namespace Flow.Launcher.Plugin.Folder
private readonly PluginJsonStorage<Settings> _storage; private readonly PluginJsonStorage<Settings> _storage;
private IContextMenu _contextMenuLoader; private IContextMenu _contextMenuLoader;
private static Dictionary<string, string> _envStringPaths;
public Main() public Main()
{ {
_storage = new PluginJsonStorage<Settings>(); _storage = new PluginJsonStorage<Settings>();
@ -48,6 +50,7 @@ namespace Flow.Launcher.Plugin.Folder
_context = context; _context = context;
_contextMenuLoader = new ContextMenuLoader(context); _contextMenuLoader = new ContextMenuLoader(context);
InitialDriverList(); InitialDriverList();
LoadEnvironmentStringPaths();
} }
public List<Result> Query(Query query) public List<Result> Query(Query query)
@ -55,10 +58,19 @@ namespace Flow.Launcher.Plugin.Folder
var results = GetUserFolderResults(query); var results = GetUserFolderResults(query);
string search = query.Search.ToLower(); string search = query.Search.ToLower();
if (!IsDriveOrSharedFolder(search)) if (!IsDriveOrSharedFolder(search) && !IsEnvironmentVariableSearch(search))
{
return results; return results;
}
results.AddRange(QueryInternal_Directory_Exists(query)); if (IsEnvironmentVariableSearch(search))
{
results.AddRange(GetEnvironmentStringPathResults(search, query));
}
else
{
results.AddRange(QueryInternal_Directory_Exists(query.Search, query));
}
// todo why was this hack here? // todo why was this hack here?
foreach (var result in results) foreach (var result in results)
@ -69,10 +81,15 @@ namespace Flow.Launcher.Plugin.Folder
return results; return results;
} }
private static bool IsEnvironmentVariableSearch(string search)
{
return _envStringPaths != null && search.StartsWith("%");
}
private static bool IsDriveOrSharedFolder(string search) private static bool IsDriveOrSharedFolder(string search)
{ {
if (search.StartsWith(@"\\")) if (search.StartsWith(@"\\"))
{ // share folder { // shared folder
return true; return true;
} }
@ -103,7 +120,7 @@ namespace Flow.Launcher.Plugin.Folder
{ {
try try
{ {
FilesFolders.OpenLocationInExporer(path); FilesFolders.OpenPath(path);
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
@ -146,14 +163,26 @@ namespace Flow.Launcher.Plugin.Folder
} }
} }
private void LoadEnvironmentStringPaths()
{
_envStringPaths = new Dictionary<string, string>();
foreach (DictionaryEntry special in Environment.GetEnvironmentVariables())
{
if (Directory.Exists(special.Value.ToString()))
{
_envStringPaths.Add(special.Key.ToString().ToLower(), special.Value.ToString());
}
}
}
private static readonly char[] _specialSearchChars = new char[] private static readonly char[] _specialSearchChars = new char[]
{ {
'?', '*', '>' '?', '*', '>'
}; };
private List<Result> QueryInternal_Directory_Exists(Query query) private List<Result> QueryInternal_Directory_Exists(string search, Query query)
{ {
var search = query.Search;
var results = new List<Result>(); var results = new List<Result>();
var hasSpecial = search.IndexOfAny(_specialSearchChars) >= 0; var hasSpecial = search.IndexOfAny(_specialSearchChars) >= 0;
string incompleteName = ""; string incompleteName = "";
@ -243,6 +272,63 @@ namespace Flow.Launcher.Plugin.Folder
return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList(); return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList();
} }
private List<Result> GetEnvironmentStringPathSuggestions(string search, Query query)
{
var results = new List<Result>();
foreach (var p in _envStringPaths)
{
if (p.Key.StartsWith(search))
{
results.Add(CreateFolderResult($"%{p.Key}%", p.Value, p.Value, query));
}
}
return results;
}
private List<Result> GetEnvironmentStringPathResults(string envStringSearch, Query query)
{
if (envStringSearch == "%")
{ // return all environment string options as path suggestions
return GetEnvironmentStringPathSuggestions("", query);
}
var results = new List<Result>();
var search = envStringSearch.Substring(1);
if (search.EndsWith("%") && search.Length > 1)
{ // query starts and ends with a %, find an exact match from env-string paths
var exactEnvStringPath = search.Substring(0, search.Length-1);
if (_envStringPaths.ContainsKey(exactEnvStringPath))
{
var expandedPath = _envStringPaths[exactEnvStringPath];
results.Add(CreateFolderResult($"%{exactEnvStringPath}%", expandedPath, expandedPath, query));
}
}
else if (search.Contains("%"))
{ // query starts with a % and contains another % somewhere before the end
var splitSearch = search.Split("%");
var exactEnvStringPath = splitSearch[0];
// if there are more than 2 % characters in the query, don't bother
if (splitSearch.Length == 2 && _envStringPaths.ContainsKey(exactEnvStringPath))
{
var queryPartToReplace = $"%{exactEnvStringPath}%";
var expandedPath = _envStringPaths[exactEnvStringPath];
// replace the %envstring% part of the query with its expanded equivalent
var updatedSearch = envStringSearch.Replace(queryPartToReplace, expandedPath);
results.AddRange(QueryInternal_Directory_Exists(updatedSearch, query));
}
}
else
{ // query simply starts wtih a %, suggest env-string paths that match the rest of the search
results.AddRange(GetEnvironmentStringPathSuggestions(search, query));
}
return results;
}
private static Result CreateFileResult(string filePath, Query query) private static Result CreateFileResult(string filePath, Query query)
{ {
var result = new Result var result = new Result
@ -255,7 +341,7 @@ namespace Flow.Launcher.Plugin.Folder
{ {
try try
{ {
FilesFolders.OpenLocationInExporer(filePath); FilesFolders.OpenPath(filePath);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -286,7 +372,7 @@ namespace Flow.Launcher.Plugin.Folder
Score = 500, Score = 500,
Action = c => Action = c =>
{ {
FilesFolders.OpenLocationInExporer(search); FilesFolders.OpenPath(search);
return true; return true;
} }
}; };

View file

@ -220,7 +220,7 @@ namespace Flow.Launcher.Plugin.PluginManagement
"Install plugin", MessageBoxButton.YesNo, MessageBoxImage.Question); "Install plugin", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes) if (result == MessageBoxResult.Yes)
{ {
context.API.RestarApp(); context.API.RestartApp();
} }
} }
} }

View file

@ -110,7 +110,7 @@
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" /> <PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.18362.2005" /> <PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.18362.2005" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NLog" Version="4.7.0-rc1" /> <PackageReference Include="NLog" Version="4.7.0" />
<PackageReference Include="System.Runtime" Version="4.3.1" /> <PackageReference Include="System.Runtime" Version="4.3.1" />
</ItemGroup> </ItemGroup>

View file

@ -205,7 +205,7 @@ namespace Flow.Launcher.Plugin.Sys
IcoPath = "Images\\app.png", IcoPath = "Images\\app.png",
Action = c => Action = c =>
{ {
context.API.RestarApp(); context.API.RestartApp();
return false; return false;
} }
}, },

View file

@ -8,6 +8,7 @@
<AssemblyName>Flow.Launcher.Plugin.WebSearch</AssemblyName> <AssemblyName>Flow.Launcher.Plugin.WebSearch</AssemblyName>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View file

@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\..\Output\Debug\Plugins\HelloWorldFSharp\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>..\..\Output\Release\Plugins\HelloWorldFSharp\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Content Include="Images\app.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugin.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Compile Include="Main.fs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="FSharp.Core" Version="4.7.1" />
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1,31 @@
namespace HelloWorldFSharp
open Flow.Launcher.Plugin
open System.Collections.Generic
type HelloWorldFSharpPlugin() =
let mutable initContext = PluginInitContext()
interface IPlugin with
member this.Init (context: PluginInitContext) =
initContext <- context
member this.Query (query: Query) =
List<Result> [
Result (Title = "Hello World from F#",
SubTitle = sprintf "Query: %s" query.Search)
Result (Title = "Browse source code of this plugin",
SubTitle = "click to open in browser",
Action = (fun ctx ->
initContext.CurrentPluginMetadata.Website
|> System.Diagnostics.Process.Start
|> ignore
true))
Result (Title = "Trigger a tray message",
Action = (fun _ ->
initContext.API.ShowMsg ("Sample tray message", "from the F# plugin")
false))
]

View file

@ -0,0 +1,12 @@
{
"ID": "8FF5D5C1F8194958A12E8668FB7ECC04",
"ActionKeyword": "hf",
"Name": "Hello World FSharp",
"Description": "Hello World FSharp",
"Author": "Ioannis G.",
"Version": "1.0.0",
"Language": "fsharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "HelloWorldFSharp.dll",
"IcoPath": "Images\\app.png"
}