From 46ed642298e08c494f14733352c9e03e1962816c Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Wed, 29 Apr 2020 18:58:21 +1000 Subject: [PATCH 01/29] Fix file path not opening --- Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index 7165804a4..5c0c1bc7a 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.IO; using System.Windows; @@ -115,7 +115,7 @@ namespace Flow.Launcher.Plugin.SharedCommands var psi = new ProcessStartInfo { FileName = FileExplorerProgramName, UseShellExecute = true, Arguments = location }; try { - if (LocationExists(location)) + if (LocationExists(fileOrFolderPath) || FileExits(fileOrFolderPath)) Process.Start(psi); } catch (Exception e) From df1af8f45a1bacafe7460cfe571e29175da41215 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Wed, 29 Apr 2020 18:58:52 +1000 Subject: [PATCH 02/29] Update method name to describe purpose --- Flow.Launcher.Core/Configuration/Portable.cs | 2 +- Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs | 6 +++--- Flow.Launcher/SettingWindow.xaml.cs | 2 +- Plugins/Flow.Launcher.Plugin.Folder/Main.cs | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index d08c9ae2c..c46a6102d 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -172,7 +172,7 @@ namespace Flow.Launcher.Core.Configuration "would you like to move it to a different location?", string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes) { - FilesFolders.OpenLocationInExporer(Constant.RootDirectory); + FilesFolders.OpenPath(Constant.RootDirectory); Environment.Exit(0); } diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index 5c0c1bc7a..f9888b78c 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.IO; using System.Windows; @@ -110,9 +110,9 @@ namespace Flow.Launcher.Plugin.SharedCommands 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 { if (LocationExists(fileOrFolderPath) || FileExits(fileOrFolderPath)) diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs index af8a148da..609d9e345 100644 --- a/Flow.Launcher/SettingWindow.xaml.cs +++ b/Flow.Launcher/SettingWindow.xaml.cs @@ -241,7 +241,7 @@ namespace Flow.Launcher { var directory = _viewModel.SelectedPlugin.PluginPair.Metadata.PluginDirectory; if (!string.IsNullOrEmpty(directory)) - FilesFolders.OpenLocationInExporer(directory); + FilesFolders.OpenPath(directory); } } #endregion diff --git a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs index 4283fe7f7..74ce0c92d 100644 --- a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs @@ -103,7 +103,7 @@ namespace Flow.Launcher.Plugin.Folder { try { - FilesFolders.OpenLocationInExporer(path); + FilesFolders.OpenPath(path); return true; } catch (Exception ex) @@ -255,7 +255,7 @@ namespace Flow.Launcher.Plugin.Folder { try { - FilesFolders.OpenLocationInExporer(filePath); + FilesFolders.OpenPath(filePath); } catch (Exception ex) { @@ -286,7 +286,7 @@ namespace Flow.Launcher.Plugin.Folder Score = 500, Action = c => { - FilesFolders.OpenLocationInExporer(search); + FilesFolders.OpenPath(search); return true; } }; From b44c9b6469b0ffdedd7475602cab657f2298639c Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Wed, 29 Apr 2020 19:02:57 +1000 Subject: [PATCH 03/29] Update from method name change method --- Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index f9888b78c..17c2dc511 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -123,7 +123,7 @@ namespace Flow.Launcher.Plugin.SharedCommands #if DEBUG throw e; #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 } } From d63ae1570ae316a899735482c5328fe7563ca9df Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Wed, 29 Apr 2020 19:37:16 +1000 Subject: [PATCH 04/29] Recursive delete sub folders and files --- Plugins/Flow.Launcher.Plugin.Folder/ContextMenuLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Folder/ContextMenuLoader.cs b/Plugins/Flow.Launcher.Plugin.Folder/ContextMenuLoader.cs index c083a95f6..561047932 100644 --- a/Plugins/Flow.Launcher.Plugin.Folder/ContextMenuLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.Folder/ContextMenuLoader.cs @@ -89,7 +89,7 @@ namespace Flow.Launcher.Plugin.Folder if (record.Type == ResultType.File) File.Delete(record.FullPath); else - Directory.Delete(record.FullPath); + Directory.Delete(record.FullPath, true); } catch(Exception e) { From 9ac9a2f2182602c27b8b0446d854bab129974356 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Thu, 30 Apr 2020 09:54:13 +0300 Subject: [PATCH 05/29] fix typo in IPublicAPI `RestarApp` to `RestartApp`. Mark `RestarApp` as obsolete. --- Flow.Launcher.Core/Plugin/PluginInstaller.cs | 2 +- Flow.Launcher.Plugin/IPublicAPI.cs | 6 ++++++ Flow.Launcher/PublicAPIInstance.cs | 7 ++++++- Plugins/Flow.Launcher.Plugin.PluginManagement/Main.cs | 2 +- Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 2 +- 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginInstaller.cs b/Flow.Launcher.Core/Plugin/PluginInstaller.cs index fdea98b5d..df38ca608 100644 --- a/Flow.Launcher.Core/Plugin/PluginInstaller.cs +++ b/Flow.Launcher.Core/Plugin/PluginInstaller.cs @@ -86,7 +86,7 @@ namespace Flow.Launcher.Core.Plugin "Restart Flow Launcher to take effect?", "Install plugin", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { - PluginManager.API.RestarApp(); + PluginManager.API.RestartApp(); } } } diff --git a/Flow.Launcher.Plugin/IPublicAPI.cs b/Flow.Launcher.Plugin/IPublicAPI.cs index 7fa7cefe2..2e754a0ff 100644 --- a/Flow.Launcher.Plugin/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/IPublicAPI.cs @@ -43,6 +43,12 @@ namespace Flow.Launcher.Plugin /// /// Restart Flow Launcher /// + void RestartApp(); + + /// + /// Restart Flow Launcher + /// + [Obsolete("Use RestartApp instead. This method will be removed in Flow Launcher 1.3")] void RestarApp(); /// diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 16339fb1e..530e6443c 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -54,7 +54,7 @@ namespace Flow.Launcher Application.Current.MainWindow.Close(); } - public void RestarApp() + public void RestartApp() { _mainVM.MainWindowVisibility = Visibility.Hidden; @@ -66,6 +66,11 @@ namespace Flow.Launcher UpdateManager.RestartApp(Constant.ApplicationFileName); } + public void RestarApp() + { + RestartApp(); + } + public void CheckForNewUpdate() { _settingsVM.UpdateApp(); diff --git a/Plugins/Flow.Launcher.Plugin.PluginManagement/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginManagement/Main.cs index 5b2804ed5..586513acd 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginManagement/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginManagement/Main.cs @@ -220,7 +220,7 @@ namespace Flow.Launcher.Plugin.PluginManagement "Install plugin", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { - context.API.RestarApp(); + context.API.RestartApp(); } } } diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs index f4f131279..0b57608c3 100644 --- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs @@ -205,7 +205,7 @@ namespace Flow.Launcher.Plugin.Sys IcoPath = "Images\\app.png", Action = c => { - context.API.RestarApp(); + context.API.RestartApp(); return false; } }, From 032a203224f7c9cd02db848f18d18f6905c71654 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Thu, 30 Apr 2020 10:22:28 +0300 Subject: [PATCH 06/29] add F# as an allowed plugin language * rename PluginsLoader.CSharpPlugins to the more generic DotNetPlugins * add AllowedLanguage.IsDotNet which checks for either C# or F# --- Flow.Launcher.Core/Plugin/PluginsLoader.cs | 16 ++++++++-------- Flow.Launcher.Plugin/AllowedLanguage.cs | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs index 31e1c7032..35486e794 100644 --- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs +++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs @@ -20,21 +20,21 @@ namespace Flow.Launcher.Core.Plugin public static List Plugins(List metadatas, PluginsSettings settings) { - var csharpPlugins = CSharpPlugins(metadatas).ToList(); + var dotnetPlugins = DotNetPlugins(metadatas).ToList(); var pythonPlugins = PythonPlugins(metadatas, settings.PythonDirectory); var executablePlugins = ExecutablePlugins(metadatas); - var plugins = csharpPlugins.Concat(pythonPlugins).Concat(executablePlugins).ToList(); + var plugins = dotnetPlugins.Concat(pythonPlugins).Concat(executablePlugins).ToList(); return plugins; } - public static IEnumerable CSharpPlugins(List source) + public static IEnumerable DotNetPlugins(List source) { var plugins = new List(); - var metadatas = source.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp); + var metadatas = source.Where(o => AllowedLanguage.IsDotNet(o.Language)); 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 @@ -50,7 +50,7 @@ namespace Flow.Launcher.Core.Plugin } 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; } var types = assembly.GetTypes(); @@ -61,7 +61,7 @@ namespace Flow.Launcher.Core.Plugin } 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; } IPlugin plugin; @@ -71,7 +71,7 @@ namespace Flow.Launcher.Core.Plugin } 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; } #endif diff --git a/Flow.Launcher.Plugin/AllowedLanguage.cs b/Flow.Launcher.Plugin/AllowedLanguage.cs index 9f63c09fc..827958a7b 100644 --- a/Flow.Launcher.Plugin/AllowedLanguage.cs +++ b/Flow.Launcher.Plugin/AllowedLanguage.cs @@ -12,15 +12,26 @@ get { return "CSHARP"; } } + public static string FSharp + { + get { return "FSHARP"; } + } + public static string Executable { get { return "EXECUTABLE"; } } + public static bool IsDotNet(string language) + { + return language.ToUpper() == CSharp + || language.ToUpper() == FSharp; + } + public static bool IsAllowed(string language) { - return language.ToUpper() == Python.ToUpper() - || language.ToUpper() == CSharp.ToUpper() + return IsDotNet(language) + || language.ToUpper() == Python.ToUpper() || language.ToUpper() == Executable.ToUpper(); } } From 1238d86fc520f13342a4a12b84cd1874b4418562 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Thu, 30 Apr 2020 11:37:15 +0300 Subject: [PATCH 07/29] add HelloWorldFSharp example plugin --- Flow.Launcher.sln | 15 +++++++++ .../HelloWorldFSharp/HelloWorldFSharp.fsproj | 29 +++++++++++++++++ Plugins/HelloWorldFSharp/Main.fs | 31 +++++++++++++++++++ Plugins/HelloWorldFSharp/plugin.json | 11 +++++++ 4 files changed, 86 insertions(+) create mode 100644 Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj create mode 100644 Plugins/HelloWorldFSharp/Main.fs create mode 100644 Plugins/HelloWorldFSharp/plugin.json diff --git a/Flow.Launcher.sln b/Flow.Launcher.sln index 9f1ad9499..2827cf585 100644 --- a/Flow.Launcher.sln +++ b/Flow.Launcher.sln @@ -74,6 +74,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Browse 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}" EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "HelloWorldFSharp", "Plugins\HelloWorldFSharp\HelloWorldFSharp.fsproj", "{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution 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|x86.ActiveCfg = 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 GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -332,6 +346,7 @@ Global {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {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} + {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F26ACB50-3F6C-4907-B0C9-1ADACC1D0DED} diff --git a/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj b/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj new file mode 100644 index 000000000..b4ba854e4 --- /dev/null +++ b/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj @@ -0,0 +1,29 @@ + + + + netcoreapp3.1 + false + false + + + + ..\..\Output\Debug\Plugins\HelloWorldFSharp\ + DEBUG;TRACE + + + + ..\..\Output\Release\Plugins\HelloWorldFSharp\ + + + + + Always + + + + + + + + + \ No newline at end of file diff --git a/Plugins/HelloWorldFSharp/Main.fs b/Plugins/HelloWorldFSharp/Main.fs new file mode 100644 index 000000000..15fd3afbd --- /dev/null +++ b/Plugins/HelloWorldFSharp/Main.fs @@ -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 (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)) + ] diff --git a/Plugins/HelloWorldFSharp/plugin.json b/Plugins/HelloWorldFSharp/plugin.json new file mode 100644 index 000000000..8b9746399 --- /dev/null +++ b/Plugins/HelloWorldFSharp/plugin.json @@ -0,0 +1,11 @@ +{ + "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" +} \ No newline at end of file From 1dbc061c2c987a076ee29ba44bc00d7796a4efcb Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Fri, 1 May 2020 11:56:30 +0200 Subject: [PATCH 08/29] Remove parallel loading of icons This is causing null exceptions on Wox startup and will lead to thumbnails not loaded at all. --- Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 873eb306e..0b23f030f 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -48,10 +48,10 @@ namespace Flow.Launcher.Infrastructure.Image { Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () => { - ImageCache.Usage.AsParallel().ForAll(x => + foreach (string key in _imageCache.Usage.Keys) { - Load(x.Key); - }); + Load(key); + } }); Log.Info($"|ImageLoader.Initialize|Number of preload images is <{ImageCache.Usage.Count}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}"); }); From c12dc8e543625feec2ea1e2083adbf9e9b0cc9a1 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Fri, 1 May 2020 11:58:48 +0200 Subject: [PATCH 09/29] Additional code cleanups - Use same variable naming for private members - Remove unnecessary whitespaces --- .../Image/ImageLoader.cs | 75 +++++++++++-------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 0b23f030f..567cda146 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -13,11 +13,12 @@ namespace Flow.Launcher.Infrastructure.Image { public static class ImageLoader { - private static readonly ImageCache ImageCache = new ImageCache(); - private static BinaryStorage> _storage; - private static readonly ConcurrentDictionary GuidToKey = new ConcurrentDictionary(); - private static IImageHashGenerator _hashGenerator; + private static readonly ImageCache _imageCache = new ImageCache(); + private static readonly ConcurrentDictionary _guidToKey = new ConcurrentDictionary(); + private static readonly bool _enableHashImage = true; + private static BinaryStorage> _storage; + private static IImageHashGenerator _hashGenerator; private static readonly string[] ImageExtensions = { @@ -30,20 +31,20 @@ namespace Flow.Launcher.Infrastructure.Image ".ico" }; - public static void Initialize() { _storage = new BinaryStorage>("Image"); _hashGenerator = new ImageHashGenerator(); - ImageCache.Usage = LoadStorageToConcurrentDictionary(); + _imageCache.Usage = LoadStorageToConcurrentDictionary(); foreach (var icon in new[] { Constant.DefaultIcon, Constant.ErrorIcon }) { ImageSource img = new BitmapImage(new Uri(icon)); img.Freeze(); - ImageCache[icon] = img; + _imageCache[icon] = img; } + Task.Run(() => { Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () => @@ -53,7 +54,7 @@ namespace Flow.Launcher.Infrastructure.Image Load(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) { - _storage.Save(ImageCache.CleanupAndToDictionary()); + _storage.Save(_imageCache.CleanupAndToDictionary()); } } @@ -105,11 +106,11 @@ namespace Flow.Launcher.Infrastructure.Image { 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)) @@ -133,8 +134,11 @@ namespace Flow.Launcher.Infrastructure.Image * - Solution: just load the icon */ type = ImageType.Folder; - image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, - Constant.ThumbnailSize, ThumbnailOptions.IconOnly); + image = WindowsThumbnailProvider.GetThumbnail( + path, + Constant.ThumbnailSize, + Constant.ThumbnailSize, + ThumbnailOptions.IconOnly); } else if (File.Exists(path)) @@ -154,20 +158,26 @@ namespace Flow.Launcher.Infrastructure.Image * be the case in many situations while testing. * - Solution: explicitly pass the ThumbnailOnly flag */ - image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, - Constant.ThumbnailSize, ThumbnailOptions.ThumbnailOnly); + image = WindowsThumbnailProvider.GetThumbnail( + path, + Constant.ThumbnailSize, + Constant.ThumbnailSize, + ThumbnailOptions.ThumbnailOnly); } } else { type = ImageType.File; - image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, - Constant.ThumbnailSize, ThumbnailOptions.None); + image = WindowsThumbnailProvider.GetThumbnail( + path, + Constant.ThumbnailSize, + Constant.ThumbnailSize, + ThumbnailOptions.None); } } else { - image = ImageCache[Constant.ErrorIcon]; + image = _imageCache[Constant.ErrorIcon]; path = Constant.ErrorIcon; } @@ -180,39 +190,40 @@ namespace Flow.Launcher.Infrastructure.Image { Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path}", e); type = ImageType.Error; - image = ImageCache[Constant.ErrorIcon]; - ImageCache[path] = image; + image = _imageCache[Constant.ErrorIcon]; + _imageCache[path] = image; } + return new ImageResult(image, type); } - private static bool EnableImageHash = true; - public static ImageSource Load(string path, bool loadFullImage = false) { var imageResult = LoadInternal(path, loadFullImage); var img = imageResult.ImageSource; 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 (GuidToKey.TryGetValue(hash, out string key)) - { // image already exists - img = ImageCache[key]; + if (_guidToKey.TryGetValue(hash, out string key)) + { + // image already exists + img = _imageCache[key]; } else - { // new guid - GuidToKey[hash] = path; + { + // new guid + _guidToKey[hash] = path; } } // update cache - ImageCache[path] = img; + _imageCache[path] = img; } - return img; } From 20d76462740396bf78c4a59282c8b38deda73823 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Fri, 1 May 2020 12:10:51 +0200 Subject: [PATCH 10/29] Add missing icon path --- Plugins/HelloWorldFSharp/plugin.json | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Plugins/HelloWorldFSharp/plugin.json b/Plugins/HelloWorldFSharp/plugin.json index 8b9746399..bb1e8f4ac 100644 --- a/Plugins/HelloWorldFSharp/plugin.json +++ b/Plugins/HelloWorldFSharp/plugin.json @@ -1,11 +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" + "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": "app.png" } \ No newline at end of file From ce9ca5dabdfa1475f184782c14f8588952f646e2 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Fri, 1 May 2020 16:25:32 +0200 Subject: [PATCH 11/29] Add default app.png image --- .../HelloWorldFSharp/HelloWorldFSharp.fsproj | 5 ++++- Plugins/HelloWorldFSharp/Images/app.png | Bin 0 -> 11524 bytes 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 Plugins/HelloWorldFSharp/Images/app.png diff --git a/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj b/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj index b4ba854e4..79f28e7cb 100644 --- a/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj +++ b/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -16,6 +16,9 @@ + + PreserveNewest + Always diff --git a/Plugins/HelloWorldFSharp/Images/app.png b/Plugins/HelloWorldFSharp/Images/app.png new file mode 100644 index 0000000000000000000000000000000000000000..8c9ca7971a62d99905b25ef3fb3e435e1d1ceaca GIT binary patch literal 11524 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 literal 0 HcmV?d00001 From c23073ec47abd42e5788d5dbe63842d734149e30 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Fri, 1 May 2020 16:25:43 +0200 Subject: [PATCH 12/29] Fix IcoPath --- Plugins/HelloWorldFSharp/plugin.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/HelloWorldFSharp/plugin.json b/Plugins/HelloWorldFSharp/plugin.json index bb1e8f4ac..845b93e4b 100644 --- a/Plugins/HelloWorldFSharp/plugin.json +++ b/Plugins/HelloWorldFSharp/plugin.json @@ -8,5 +8,5 @@ "Language": "fsharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "HelloWorldFSharp.dll", - "IcoPath": "app.png" + "IcoPath": "Images\\app.png" } \ No newline at end of file From 07be7e2beaab8b4e9ce97f910fe62c9f8cc9f3ff Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Fri, 1 May 2020 12:42:32 +0300 Subject: [PATCH 13/29] bump PropertyChanged.Fody to 3.2.8 This outdated dependency causes `dotnet build`, `dotnet pack` etc to fail --- Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +- Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj | 4 ++-- Flow.Launcher/Flow.Launcher.csproj | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index d5fc55da8..5b471cabd 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -55,7 +55,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index 0c6df2b59..82fbb31d5 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -55,7 +55,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 4baeb69e4..f2f6afbd1 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -64,7 +64,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From be3b74d9bb48eadb03426fd63095965632fe4366 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Sat, 2 May 2020 13:14:51 +0300 Subject: [PATCH 14/29] fix issue extracting file thumbnails in parallel --- Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 567cda146..e5deea023 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -49,10 +49,10 @@ namespace Flow.Launcher.Infrastructure.Image { Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () => { - foreach (string key in _imageCache.Usage.Keys) + ImageCache.Usage.AsParallel().ForAll(x => { - Load(key); - } + Load(x.Key); + }); }); Log.Info($"|ImageLoader.Initialize|Number of preload images is <{_imageCache.Usage.Count}>, Images Number: {_imageCache.CacheSize()}, Unique Items {_imageCache.UniqueImagesInCache()}"); }); @@ -172,7 +172,7 @@ namespace Flow.Launcher.Infrastructure.Image path, Constant.ThumbnailSize, Constant.ThumbnailSize, - ThumbnailOptions.None); + ThumbnailOptions.ThumbnailOnly); } } else From 1f94b87d360a4fcf352829dc553a72a2b4fd943b Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Sat, 2 May 2020 13:11:39 +0200 Subject: [PATCH 15/29] Fix variable name --- Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index e5deea023..e27bf0377 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -49,7 +49,7 @@ namespace Flow.Launcher.Infrastructure.Image { Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () => { - ImageCache.Usage.AsParallel().ForAll(x => + _imageCache.Usage.AsParallel().ForAll(x => { Load(x.Key); }); From a3b25d107ca7f970fbbd6b5ac9d14247662c88fa Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Sat, 2 May 2020 13:12:34 +0200 Subject: [PATCH 16/29] Add retry logic for thumbnail loading --- .../Image/ImageLoader.cs | 124 ++++++++++-------- 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index e27bf0377..8ed43d97f 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -100,8 +100,8 @@ namespace Flow.Launcher.Infrastructure.Image private static ImageResult LoadInternal(string path, bool loadFullImage = false) { - ImageSource image; - ImageType type = ImageType.Error; + ImageResult imageResult; + try { if (string.IsNullOrEmpty(path)) @@ -125,78 +125,94 @@ namespace Flow.Launcher.Infrastructure.Image 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. - * 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 = WindowsThumbnailProvider.GetThumbnail( - path, - Constant.ThumbnailSize, - Constant.ThumbnailSize, - ThumbnailOptions.IconOnly); - + // Retry to get thumbnail for certain images when the first try failed + imageResult = GetThumbnailResult(ref path, loadFullImage); } - else if (File.Exists(path)) + catch (System.Exception e2) { - var extension = Path.GetExtension(path).ToLower(); - if (ImageExtensions.Contains(extension)) + Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e); + 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; - 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); - } + image = LoadFullImage(path); } else { - type = ImageType.File; - image = WindowsThumbnailProvider.GetThumbnail( - path, - Constant.ThumbnailSize, - Constant.ThumbnailSize, - ThumbnailOptions.ThumbnailOnly); + /* 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 = GetThumbnail(path, ThumbnailOptions.ThumbnailOnly); } } else { - image = _imageCache[Constant.ErrorIcon]; - path = Constant.ErrorIcon; - } - - if (type != ImageType.Error) - { - image.Freeze(); + type = ImageType.File; + image = GetThumbnail(path, ThumbnailOptions.None); } } - catch (System.Exception e) + else { - Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path}", e); - type = ImageType.Error; image = _imageCache[Constant.ErrorIcon]; - _imageCache[path] = image; + path = Constant.ErrorIcon; + } + + if (type != ImageType.Error) + { + image.Freeze(); } return new ImageResult(image, type); } + 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) { var imageResult = LoadInternal(path, loadFullImage); From 1dcaf62e2700419014c5e1cebd8c9763fb0da4b1 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Sat, 2 May 2020 14:13:20 +0300 Subject: [PATCH 17/29] add dependency to FSharp.Core ensure there are no runtime errors when FSharp.Core cannot be located: * add reference to FSharp.Core 4.7.1 in Flow.Launcher.Core * update FSharp.Core to 4.7.1 in HelloWorldFSharp --- Flow.Launcher.Core/Flow.Launcher.Core.csproj | 1 + Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index 5b471cabd..cd939e401 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -52,6 +52,7 @@ + diff --git a/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj b/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj index 79f28e7cb..d688ab6a9 100644 --- a/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj +++ b/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj @@ -29,4 +29,8 @@ + + + + \ No newline at end of file From 6db1f908c3f7b58414192e48d871f52607ef018d Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Sat, 2 May 2020 14:23:33 +0300 Subject: [PATCH 18/29] update dependencies in Flow.Launcher.Test * Microsoft.CodeCoverage 16.4.0 -> 16.6.1 * Microsoft.NET.Test.Sdk 16.4.0 -> 16.6.1 * Microsoft.TestPlatform.ObjectModel 16.4.0 -> 16.6.1 * Microsoft.TestPlatform.TestHost 16.4.0 -> 16.6.1 * Moq 4.13.1 -> 4.14.1 * NUnit3TestAdapter 3.15.1 -> 3.16.1 --- Flow.Launcher.Test/Flow.Launcher.Test.csproj | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj index 2f54813e1..daeeb6bdd 100644 --- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj +++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj @@ -46,10 +46,13 @@ - + - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + From 0cedc8b8f240dd309d875bd80f38267ea3819aae Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Sat, 2 May 2020 14:28:33 +0300 Subject: [PATCH 19/29] bump NLog dependency in Program plugin from 4.7.0-rc1 to 4.7.0 --- .../Flow.Launcher.Plugin.Program.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj index 4bc5ba8cd..6208881d4 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj +++ b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj @@ -110,7 +110,7 @@ - + From ef95913abad64b6d69b9550f994ad7eebf542c40 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Sat, 2 May 2020 19:52:41 +0300 Subject: [PATCH 20/29] update projects with SatelliteResourceLanguages Without this property set, the output folder is populated with multiple culture-specific versions of `Fsharp.Core.resources.dll` --- Flow.Launcher.Core/Flow.Launcher.Core.csproj | 1 + Flow.Launcher.Test/Flow.Launcher.Test.csproj | 1 + Flow.Launcher/Flow.Launcher.csproj | 3 ++- .../Flow.Launcher.Plugin.WebSearch.csproj | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index cd939e401..fa3f10fa7 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -11,6 +11,7 @@ false false false + en diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj index daeeb6bdd..2dbf1a9d3 100644 --- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj +++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj @@ -10,6 +10,7 @@ false + en diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index f2f6afbd1..7049d9c4d 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -1,4 +1,4 @@ - + WinExe @@ -11,6 +11,7 @@ false false false + en diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj b/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj index 21695ffcf..d159e9bc0 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj @@ -8,6 +8,7 @@ Flow.Launcher.Plugin.WebSearch false false + en From 4e67f28a64691fcc0141c2c04733a104b7f54b2f Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Sun, 3 May 2020 14:32:52 +1000 Subject: [PATCH 21/29] Update explanation wording --- Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 8ed43d97f..ed3a6584d 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -131,7 +131,7 @@ namespace Flow.Launcher.Infrastructure.Image { try { - // Retry to get thumbnail for certain images when the first try failed + // Get thumbnail may fail for certain images on the first try, retry again has proven to work imageResult = GetThumbnailResult(ref path, loadFullImage); } catch (System.Exception e2) From 8ee168bb12ce1658ba0a372286f3f1806396829a Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Sun, 3 May 2020 14:00:01 +0300 Subject: [PATCH 22/29] plugin/folder: handle environment string paths --- Plugins/Flow.Launcher.Plugin.Folder/Main.cs | 103 +++++++++++++++++++- 1 file changed, 99 insertions(+), 4 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs index 74ce0c92d..dafd1a90e 100644 --- a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs @@ -27,6 +27,8 @@ namespace Flow.Launcher.Plugin.Folder private readonly PluginJsonStorage _storage; private IContextMenu _contextMenuLoader; + private static Dictionary _envStringPaths; + public Main() { _storage = new PluginJsonStorage(); @@ -48,6 +50,7 @@ namespace Flow.Launcher.Plugin.Folder _context = context; _contextMenuLoader = new ContextMenuLoader(context); InitialDriverList(); + LoadEnvironmentStringPaths(); } public List Query(Query query) @@ -58,7 +61,14 @@ namespace Flow.Launcher.Plugin.Folder if (!IsDriveOrSharedFolder(search)) return results; - results.AddRange(QueryInternal_Directory_Exists(query)); + if (search.StartsWith("%")) + { + results.AddRange(GetEnvironmentStringPathResults(search, query)); + } + else + { + results.AddRange(QueryInternal_Directory_Exists(query.Search, query)); + } // todo why was this hack here? foreach (var result in results) @@ -72,7 +82,12 @@ namespace Flow.Launcher.Plugin.Folder private static bool IsDriveOrSharedFolder(string search) { if (search.StartsWith(@"\\")) - { // share folder + { // shared folder + return true; + } + + if (_envStringPaths != null && search.StartsWith("%")) + { // environment string formatted folder return true; } @@ -146,14 +161,37 @@ namespace Flow.Launcher.Plugin.Folder } } + private void LoadEnvironmentStringPaths() + { + _envStringPaths = new Dictionary(); + + var specialPaths = + new Dictionary { + { "appdata", Environment.SpecialFolder.ApplicationData }, + { "localappdata", Environment.SpecialFolder.LocalApplicationData }, + { "programfiles", Environment.SpecialFolder.ProgramFiles }, + { "programfiles(x86)", Environment.SpecialFolder.ProgramFilesX86 }, + { "programdata", Environment.SpecialFolder.CommonApplicationData }, + { "userprofile", Environment.SpecialFolder.UserProfile } + }; + + foreach (var special in specialPaths) + { + _envStringPaths.Add(special.Key, Environment.GetFolderPath(special.Value)); + } + + var tempDirectoryPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Temp"); + + _envStringPaths.Add("temp", tempDirectoryPath); + } + private static readonly char[] _specialSearchChars = new char[] { '?', '*', '>' }; - private List QueryInternal_Directory_Exists(Query query) + private List QueryInternal_Directory_Exists(string search, Query query) { - var search = query.Search; var results = new List(); var hasSpecial = search.IndexOfAny(_specialSearchChars) >= 0; string incompleteName = ""; @@ -243,6 +281,63 @@ namespace Flow.Launcher.Plugin.Folder return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList(); } + private List GetEnvironmentStringPathSuggestions(string search, Query query) + { + var results = new List(); + foreach (var p in _envStringPaths) + { + if (p.Key.StartsWith(search)) + { + results.Add(CreateFolderResult($"%{p.Key}%", p.Value, p.Value, query)); + } + } + return results; + } + + private List GetEnvironmentStringPathResults(string envStringSearch, Query query) + { + if (envStringSearch == "%") + { // return all environment string options as path suggestions + return GetEnvironmentStringPathSuggestions("", query); + } + + var results = new List(); + 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) { var result = new Result From a66b4cd057c661d5ca43ee184d8f49f46c22b8b5 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Sun, 3 May 2020 15:57:32 +0200 Subject: [PATCH 23/29] New method to check for environment variable --- Plugins/Flow.Launcher.Plugin.Folder/Main.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs index dafd1a90e..663574c98 100644 --- a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs @@ -58,10 +58,12 @@ namespace Flow.Launcher.Plugin.Folder var results = GetUserFolderResults(query); string search = query.Search.ToLower(); - if (!IsDriveOrSharedFolder(search)) + if (!IsDriveOrSharedFolder(search) && !IsEnvironmentVariableSearch(search)) + { return results; + } - if (search.StartsWith("%")) + if (IsEnvironmentVariableSearch(search)) { results.AddRange(GetEnvironmentStringPathResults(search, query)); } @@ -79,6 +81,11 @@ namespace Flow.Launcher.Plugin.Folder return results; } + private static bool IsEnvironmentVariableSearch(string search) + { + return _envStringPaths != null && search.StartsWith("%"); + } + private static bool IsDriveOrSharedFolder(string search) { if (search.StartsWith(@"\\")) @@ -86,11 +93,6 @@ namespace Flow.Launcher.Plugin.Folder return true; } - if (_envStringPaths != null && search.StartsWith("%")) - { // environment string formatted folder - return true; - } - if (_driverNames != null && _driverNames.Any(search.StartsWith)) { // normal drive letter return true; From 31501a1a9e1f22070b475c49bbd1b6322fdab516 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Sun, 3 May 2020 16:01:38 +0200 Subject: [PATCH 24/29] Load environment variables from system --- Plugins/Flow.Launcher.Plugin.Folder/Main.cs | 22 ++++++--------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs index 663574c98..d8ad5d748 100644 --- a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs @@ -166,25 +166,15 @@ namespace Flow.Launcher.Plugin.Folder private void LoadEnvironmentStringPaths() { _envStringPaths = new Dictionary(); - - var specialPaths = - new Dictionary { - { "appdata", Environment.SpecialFolder.ApplicationData }, - { "localappdata", Environment.SpecialFolder.LocalApplicationData }, - { "programfiles", Environment.SpecialFolder.ProgramFiles }, - { "programfiles(x86)", Environment.SpecialFolder.ProgramFilesX86 }, - { "programdata", Environment.SpecialFolder.CommonApplicationData }, - { "userprofile", Environment.SpecialFolder.UserProfile } - }; - foreach (var special in specialPaths) + var specialPaths = System.Environment.GetEnvironmentVariables(); + foreach (DictionaryEntry special in specialPaths) { - _envStringPaths.Add(special.Key, Environment.GetFolderPath(special.Value)); + if (Directory.Exists(special.Value.ToString())) + { + _envStringPaths.Add(special.Key.ToString().ToLower(), special.Value.ToString()); + } } - - var tempDirectoryPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Temp"); - - _envStringPaths.Add("temp", tempDirectoryPath); } private static readonly char[] _specialSearchChars = new char[] From 64de0ceef33da28cf7297691247e54fa53dea48c Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Sun, 3 May 2020 16:02:31 +0200 Subject: [PATCH 25/29] Remove unused usings --- Plugins/Flow.Launcher.Plugin.Folder/Main.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs index d8ad5d748..4f6d26590 100644 --- a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs @@ -1,6 +1,6 @@ using System; +using System.Collections; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Windows; From cfdbd19d99f0ba78c6c69e63084dfe6192cee775 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Sun, 3 May 2020 18:05:01 +0200 Subject: [PATCH 26/29] Remove variable and use returned dictionary directly --- Plugins/Flow.Launcher.Plugin.Folder/Main.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs index 4f6d26590..7b44b110f 100644 --- a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs @@ -167,8 +167,7 @@ namespace Flow.Launcher.Plugin.Folder { _envStringPaths = new Dictionary(); - var specialPaths = System.Environment.GetEnvironmentVariables(); - foreach (DictionaryEntry special in specialPaths) + foreach (DictionaryEntry special in Environment.GetEnvironmentVariables()) { if (Directory.Exists(special.Value.ToString())) { From 10c16f059e1254b4a41aed1980e1d937779bec1f Mon Sep 17 00:00:00 2001 From: Grzegorz Dziedzic Date: Sun, 3 May 2020 19:17:16 +0200 Subject: [PATCH 27/29] Enhance mod+num launching --- .../UserSettings/Settings.cs | 1 + Flow.Launcher/Converters/OrdinalConverter.cs | 22 +++++++++++++++++++ Flow.Launcher/Languages/da.xaml | 1 + Flow.Launcher/Languages/de.xaml | 1 + Flow.Launcher/Languages/en.xaml | 1 + Flow.Launcher/Languages/fr.xaml | 1 + Flow.Launcher/Languages/it.xaml | 1 + Flow.Launcher/Languages/ja.xaml | 1 + Flow.Launcher/Languages/ko.xaml | 1 + Flow.Launcher/Languages/nb-NO.xaml | 1 + Flow.Launcher/Languages/nl.xaml | 1 + Flow.Launcher/Languages/pl.xaml | 1 + Flow.Launcher/Languages/pt-br.xaml | 1 + Flow.Launcher/Languages/ru.xaml | 1 + Flow.Launcher/Languages/sk.xaml | 1 + Flow.Launcher/Languages/sr.xaml | 1 + Flow.Launcher/Languages/tr.xaml | 1 + Flow.Launcher/Languages/uk-UA.xaml | 1 + Flow.Launcher/Languages/zh-cn.xaml | 1 + Flow.Launcher/Languages/zh-tw.xaml | 1 + Flow.Launcher/MainWindow.xaml | 18 +++++++-------- Flow.Launcher/ResultListBox.xaml | 3 +++ Flow.Launcher/SettingWindow.xaml | 16 ++++++++++---- Flow.Launcher/ViewModel/MainViewModel.cs | 10 +++++++++ .../ViewModel/SettingWindowViewModel.cs | 1 + 25 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 Flow.Launcher/Converters/OrdinalConverter.cs diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index dbb47fd8e..9ea71f683 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -10,6 +10,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings public class Settings : BaseModel { public string Hotkey { get; set; } = "Alt + Space"; + public string OpenResultModifiers { get; set; } = "Alt"; public string Language { get; set; } = "en"; public string Theme { get; set; } = "Dark"; public string QueryBoxFont { get; set; } = FontFamily.GenericSansSerif.Name; diff --git a/Flow.Launcher/Converters/OrdinalConverter.cs b/Flow.Launcher/Converters/OrdinalConverter.cs new file mode 100644 index 000000000..970ed183c --- /dev/null +++ b/Flow.Launcher/Converters/OrdinalConverter.cs @@ -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(); + } +} diff --git a/Flow.Launcher/Languages/da.xaml b/Flow.Launcher/Languages/da.xaml index 4c3d4bd85..49d3ef37b 100644 --- a/Flow.Launcher/Languages/da.xaml +++ b/Flow.Launcher/Languages/da.xaml @@ -51,6 +51,7 @@ Genvejstast Flow Launcher genvejstast + Åbn resultatmodifikatorer Tilpasset søgegenvejstast Slet Rediger diff --git a/Flow.Launcher/Languages/de.xaml b/Flow.Launcher/Languages/de.xaml index d1eae3124..67e33cab4 100644 --- a/Flow.Launcher/Languages/de.xaml +++ b/Flow.Launcher/Languages/de.xaml @@ -51,6 +51,7 @@ Tastenkombination Flow Launcher Tastenkombination + Öffnen Sie die Ergebnismodifikatoren Benutzerdefinierte Abfrage Tastenkombination Löschen Bearbeiten diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 46519f058..7d5baa424 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -60,6 +60,7 @@ Hotkey Flow Launcher Hotkey + Open Result Modifiers Custom Query Hotkey Delete Edit diff --git a/Flow.Launcher/Languages/fr.xaml b/Flow.Launcher/Languages/fr.xaml index 4ceb06249..39ee0c74d 100644 --- a/Flow.Launcher/Languages/fr.xaml +++ b/Flow.Launcher/Languages/fr.xaml @@ -55,6 +55,7 @@ Raccourcis Ouvrir Flow Launcher + Modificateurs de résultats ouverts Requêtes personnalisées Supprimer Modifier diff --git a/Flow.Launcher/Languages/it.xaml b/Flow.Launcher/Languages/it.xaml index 381864f8a..18795ed62 100644 --- a/Flow.Launcher/Languages/it.xaml +++ b/Flow.Launcher/Languages/it.xaml @@ -55,6 +55,7 @@ Tasti scelta rapida Tasto scelta rapida Flow Launcher + Apri modificatori di risultato Tasti scelta rapida per ricerche personalizzate Cancella Modifica diff --git a/Flow.Launcher/Languages/ja.xaml b/Flow.Launcher/Languages/ja.xaml index 0fd5e3e79..eb18ac3fa 100644 --- a/Flow.Launcher/Languages/ja.xaml +++ b/Flow.Launcher/Languages/ja.xaml @@ -58,6 +58,7 @@ ホットキー Flow Launcher ホットキー + 結果修飾子を開く カスタムクエリ ホットキー 削除 編集 diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml index 2f7d538dc..4fca622e4 100644 --- a/Flow.Launcher/Languages/ko.xaml +++ b/Flow.Launcher/Languages/ko.xaml @@ -55,6 +55,7 @@ 핫키 Flow Launcher 핫키 + 결과 수정 자 열기 사용자지정 쿼리 핫키 삭제 편집 diff --git a/Flow.Launcher/Languages/nb-NO.xaml b/Flow.Launcher/Languages/nb-NO.xaml index 035b0cbdf..dc87a58ec 100644 --- a/Flow.Launcher/Languages/nb-NO.xaml +++ b/Flow.Launcher/Languages/nb-NO.xaml @@ -55,6 +55,7 @@ Hurtigtast Flow Launcher-hurtigtast + Åpne resultatmodifiserere Egendefinerd spørringshurtigtast Slett Rediger diff --git a/Flow.Launcher/Languages/nl.xaml b/Flow.Launcher/Languages/nl.xaml index be18beb9c..ed2a52e9d 100644 --- a/Flow.Launcher/Languages/nl.xaml +++ b/Flow.Launcher/Languages/nl.xaml @@ -51,6 +51,7 @@ Sneltoets Flow Launcher Sneltoets + Open resultaatmodificatoren Custom Query Sneltoets Verwijder Bewerken diff --git a/Flow.Launcher/Languages/pl.xaml b/Flow.Launcher/Languages/pl.xaml index 249878ed3..d94ff5295 100644 --- a/Flow.Launcher/Languages/pl.xaml +++ b/Flow.Launcher/Languages/pl.xaml @@ -51,6 +51,7 @@ Skrót klawiszowy Skrót klawiszowy Flow Launcher + Modyfikatory klawiszów otwierających wyniki Skrót klawiszowy niestandardowych zapytań Usuń Edytuj diff --git a/Flow.Launcher/Languages/pt-br.xaml b/Flow.Launcher/Languages/pt-br.xaml index 2036744e8..b22ed05ea 100644 --- a/Flow.Launcher/Languages/pt-br.xaml +++ b/Flow.Launcher/Languages/pt-br.xaml @@ -55,6 +55,7 @@ Atalho Atalho do Flow Launcher + Modificadores de resultado aberto Atalho de Consulta Personalizada Apagar Editar diff --git a/Flow.Launcher/Languages/ru.xaml b/Flow.Launcher/Languages/ru.xaml index 66a463dcb..93d1f476a 100644 --- a/Flow.Launcher/Languages/ru.xaml +++ b/Flow.Launcher/Languages/ru.xaml @@ -51,6 +51,7 @@ Горячие клавиши Горячая клавиша Flow Launcher + Модификаторы открытого результата Задаваемые горячие клавиши для запросов Удалить Изменить diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml index 824096c4c..76450f5d8 100644 --- a/Flow.Launcher/Languages/sk.xaml +++ b/Flow.Launcher/Languages/sk.xaml @@ -56,6 +56,7 @@ Klávesová skratka Klávesová skratka pre Flow Launcher + Otvorte modifikátory výsledkov Vlastná klávesová skratka pre dopyt Odstrániť Upraviť diff --git a/Flow.Launcher/Languages/sr.xaml b/Flow.Launcher/Languages/sr.xaml index 22aabb37f..bfae4917f 100644 --- a/Flow.Launcher/Languages/sr.xaml +++ b/Flow.Launcher/Languages/sr.xaml @@ -55,6 +55,7 @@ Prečica Flow Launcher prečica + Отворите модификаторе резултата prečica za ručno dodat upit Obriši Izmeni diff --git a/Flow.Launcher/Languages/tr.xaml b/Flow.Launcher/Languages/tr.xaml index cc287f372..da61d1c5d 100644 --- a/Flow.Launcher/Languages/tr.xaml +++ b/Flow.Launcher/Languages/tr.xaml @@ -59,6 +59,7 @@ Kısayol Tuşu Flow Launcher Kısayolu + Açık Sonuç Değiştiricileri Özel Sorgu Kısayolları Sil Düzenle diff --git a/Flow.Launcher/Languages/uk-UA.xaml b/Flow.Launcher/Languages/uk-UA.xaml index c7e84c231..baad144a7 100644 --- a/Flow.Launcher/Languages/uk-UA.xaml +++ b/Flow.Launcher/Languages/uk-UA.xaml @@ -51,6 +51,7 @@ Гарячі клавіші Гаряча клавіша Flow Launcher + Відкриті модифікатори результатів Задані гарячі клавіші для запитів Видалити Змінити diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml index 5801b678a..b5d03b858 100644 --- a/Flow.Launcher/Languages/zh-cn.xaml +++ b/Flow.Launcher/Languages/zh-cn.xaml @@ -58,6 +58,7 @@ 热键 Flow Launcher激活热键 + 开放结果修饰符 自定义查询热键 删除 编辑 diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml index f1df1a6d5..81277ae3e 100644 --- a/Flow.Launcher/Languages/zh-tw.xaml +++ b/Flow.Launcher/Languages/zh-tw.xaml @@ -51,6 +51,7 @@ 熱鍵 Flow Launcher 執行熱鍵 + 開放結果修飾符 自定義熱鍵查詢 刪除 編輯 diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index 74185fcbd..485f58b47 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -48,15 +48,15 @@ - - - - - - - - - + + + + + + + + + diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml index c9ca658f2..c79ba40dd 100644 --- a/Flow.Launcher/ResultListBox.xaml +++ b/Flow.Launcher/ResultListBox.xaml @@ -33,6 +33,7 @@ Cursor="Hand" UseLayoutRounding="False"> + @@ -46,6 +47,8 @@ + diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index be87e4f52..cd56332d7 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -287,9 +287,10 @@ + - + - + + + + + Margin="0 5 0 0" Grid.Row="3"> @@ -322,7 +330,7 @@ -