From 24fa234c9bb61cad0b927eccda608053e546b152 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Wed, 11 Dec 2019 19:42:10 +0100 Subject: [PATCH 01/20] Allow comma in input expression Calculator now supports a comma as decimal seperator. --- Plugins/Wox.Plugin.Calculator/Main.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Plugins/Wox.Plugin.Calculator/Main.cs b/Plugins/Wox.Plugin.Calculator/Main.cs index fab0b8e03..010ff0b6f 100644 --- a/Plugins/Wox.Plugin.Calculator/Main.cs +++ b/Plugins/Wox.Plugin.Calculator/Main.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows; @@ -34,7 +34,8 @@ namespace Wox.Plugin.Caculator try { - var result = MagesEngine.Interpret(query.Search); + var expression = query.Search.Replace(",", "."); + var result = MagesEngine.Interpret(expression); if (result.ToString() == "NaN") result = Context.API.GetTranslation("wox_plugin_calculator_not_a_number"); From d204df2b18a0448b62d38ced7de44c81a89743e6 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Wed, 11 Dec 2019 19:42:27 +0100 Subject: [PATCH 02/20] Improve format --- Plugins/Wox.Plugin.Calculator/Main.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Plugins/Wox.Plugin.Calculator/Main.cs b/Plugins/Wox.Plugin.Calculator/Main.cs index 010ff0b6f..c8c7fcb0b 100644 --- a/Plugins/Wox.Plugin.Calculator/Main.cs +++ b/Plugins/Wox.Plugin.Calculator/Main.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows; @@ -28,7 +28,8 @@ namespace Wox.Plugin.Caculator public List Query(Query query) { - if (query.Search.Length <= 2 // don't affect when user only input "e" or "i" keyword + // Don't affect when user only input "e" or "i" keyword + if (query.Search.Length <= 2 || !RegValidExpressChar.IsMatch(query.Search) || !IsBracketComplete(query.Search)) return new List(); @@ -43,7 +44,6 @@ namespace Wox.Plugin.Caculator if (result is Function) result = Context.API.GetTranslation("wox_plugin_calculator_expression_not_complete"); - if (!string.IsNullOrEmpty(result?.ToString())) { return new List From cb9e045c7f6c9b6449f035f68b40525180b9f758 Mon Sep 17 00:00:00 2001 From: clueless <14300910+theClueless@users.noreply.github.com> Date: Fri, 21 Feb 2020 23:12:58 +0200 Subject: [PATCH 03/20] catch plugin init fails - stop Wox from not starting up and crushing and disable and explain the user what is the probalmatic plugin --- Wox.Core/Plugin/PluginManager.cs | 35 +++++++++++++++++++----- Wox.Infrastructure/Logger/Log.cs | 47 +++++++++++++++++++++++++++++--- Wox.Plugin/IPublicAPI.cs | 2 +- Wox.Plugin/PluginMetadata.cs | 3 ++ Wox/PublicAPIInstance.cs | 6 ++-- 5 files changed, 78 insertions(+), 15 deletions(-) diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index fc9afb740..27e2d4851 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -92,21 +93,36 @@ namespace Wox.Core.Plugin Settings.UpdatePluginSettings(_metadatas); AllPlugins = PluginsLoader.Plugins(_metadatas, Settings); } + + /// + /// Call initialize for all plugins + /// + /// return the list of failed to init plugins or null for none public static void InitializePlugins(IPublicAPI api) { API = api; + var failedPlugins = new ConcurrentQueue(); Parallel.ForEach(AllPlugins, pair => { - var milliseconds = Stopwatch.Debug($"|PluginManager.InitializePlugins|Init method time cost for <{pair.Metadata.Name}>", () => + try { - pair.Plugin.Init(new PluginInitContext + var milliseconds = Stopwatch.Debug($"|PluginManager.InitializePlugins|Init method time cost for <{pair.Metadata.Name}>", () => { - CurrentPluginMetadata = pair.Metadata, - API = API + pair.Plugin.Init(new PluginInitContext + { + CurrentPluginMetadata = pair.Metadata, + API = API + }); }); - }); - pair.Metadata.InitTime += milliseconds; - Log.Info($"|PluginManager.InitializePlugins|Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>"); + pair.Metadata.InitTime += milliseconds; + Log.Info($"|PluginManager.InitializePlugins|Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>"); + } + catch (Exception e) + { + Log.Exception(nameof(PluginManager), $"Fail to Init plugin: {pair.Metadata.Name}", e); + pair.Metadata.Disabled = true; // TODO: not sure this really disable it later on + failedPlugins.Enqueue(pair); + } }); _contextMenuPlugins = GetPluginsForInterface(); @@ -121,6 +137,11 @@ namespace Wox.Core.Plugin .ForEach(x => NonGlobalPlugins[x] = plugin); } + if (failedPlugins.Any()) + { + var failed = string.Join(",", failedPlugins.Select(x => x.Metadata.Name)); + API.ShowMsg($"Fail to Init Plugins", $"Plugins: {failed} - fail to load and would be disabled, please contact plugin creator for help", "", false); + } } public static void InstallPlugin(string path) diff --git a/Wox.Infrastructure/Logger/Log.cs b/Wox.Infrastructure/Logger/Log.cs index 10e8128c5..349920076 100644 --- a/Wox.Infrastructure/Logger/Log.cs +++ b/Wox.Infrastructure/Logger/Log.cs @@ -11,7 +11,7 @@ namespace Wox.Infrastructure.Logger { public const string DirectoryName = "Logs"; - public static string CurrentLogDirectory { get; private set; } + public static string CurrentLogDirectory { get; } static Log() { @@ -53,6 +53,14 @@ namespace Wox.Infrastructure.Logger [MethodImpl(MethodImplOptions.Synchronized)] public static void Exception(string className, string message, System.Exception exception, [CallerMemberName] string methodName = "") + { + var classNameWithMethod = CheckClassAndMessageAndReturnFullClassWithMethod(className, message, methodName); + + ExceptionInternal(classNameWithMethod, message, exception); + } + + private static string CheckClassAndMessageAndReturnFullClassWithMethod(string className, string message, + string methodName) { if (string.IsNullOrWhiteSpace(className)) { @@ -60,16 +68,17 @@ namespace Wox.Infrastructure.Logger } if (string.IsNullOrWhiteSpace(message)) - { // todo: not sure we really need that + { + // todo: not sure we really need that LogFaultyFormat($"Fail to specify a message during logging"); } if (!string.IsNullOrWhiteSpace(methodName)) { - className += "." + methodName; + return className + "." + methodName; } - ExceptionInternal(className, message, exception); + return className; } private static void ExceptionInternal(string classAndMethod, string message, System.Exception e) @@ -140,18 +149,48 @@ namespace Wox.Infrastructure.Logger LogInternal(message, LogLevel.Error); } + public static void Error(string className, string message, [CallerMemberName] string methodName = "") + { + LogInternal(LogLevel.Error, className, message, methodName); + } + + private static void LogInternal(LogLevel level, string className, string message, [CallerMemberName] string methodName = "") + { + var classNameWithMethod = CheckClassAndMessageAndReturnFullClassWithMethod(className, message, methodName); + + var logger = LogManager.GetLogger(classNameWithMethod); + + System.Diagnostics.Debug.WriteLine($"{level.Name}|{message}"); + logger.Log(level, message); + } + + public static void Debug(string className, string message, [CallerMemberName] string methodName = "") + { + LogInternal(LogLevel.Debug, className, message, methodName); + } + /// example: "|prefix|unprefixed" public static void Debug(string message) { LogInternal(message, LogLevel.Debug); } + public static void Info(string className, string message, [CallerMemberName] string methodName = "") + { + LogInternal(LogLevel.Info, className, message, methodName); + } + /// example: "|prefix|unprefixed" public static void Info(string message) { LogInternal(message, LogLevel.Info); } + public static void Warn(string className, string message, [CallerMemberName] string methodName = "") + { + LogInternal(LogLevel.Warn, className, message, methodName); + } + /// example: "|prefix|unprefixed" public static void Warn(string message) { diff --git a/Wox.Plugin/IPublicAPI.cs b/Wox.Plugin/IPublicAPI.cs index eb3f18fa7..8dc838963 100644 --- a/Wox.Plugin/IPublicAPI.cs +++ b/Wox.Plugin/IPublicAPI.cs @@ -76,7 +76,7 @@ namespace Wox.Plugin /// Message title /// Message subtitle /// Message icon path (relative path to your plugin folder) - void ShowMsg(string title, string subTitle = "", string iconPath = ""); + void ShowMsg(string title, string subTitle = "", string iconPath = "", bool useMainWindowAsOwner = true); /// /// Open setting dialog diff --git a/Wox.Plugin/PluginMetadata.cs b/Wox.Plugin/PluginMetadata.cs index 5b4feb88e..64b8b032c 100644 --- a/Wox.Plugin/PluginMetadata.cs +++ b/Wox.Plugin/PluginMetadata.cs @@ -46,6 +46,9 @@ namespace Wox.Plugin [Obsolete("Use IcoPath")] public string FullIcoPath => IcoPath; + /// + /// Init time include both plugin load time and init time + /// [JsonIgnore] public long InitTime { get; set; } [JsonIgnore] diff --git a/Wox/PublicAPIInstance.cs b/Wox/PublicAPIInstance.cs index ab198d6bf..314fc13b6 100644 --- a/Wox/PublicAPIInstance.cs +++ b/Wox/PublicAPIInstance.cs @@ -91,12 +91,12 @@ namespace Wox _mainVM.MainWindowVisibility = Visibility.Visible; } - public void ShowMsg(string title, string subTitle = "", string iconPath = "") + public void ShowMsg(string title, string subTitle = "", string iconPath = "", bool useMainWindowAsOwner = true) { Application.Current.Dispatcher.Invoke(() => { - var m = new Msg { Owner = Application.Current.MainWindow }; - m.Show(title, subTitle, iconPath); + var msg = useMainWindowAsOwner ? new Msg {Owner = Application.Current.MainWindow} : new Msg(); + msg.Show(title, subTitle, iconPath); }); } From e1e7387c73e928c4c05b6d73ce09a52f7cbf003e Mon Sep 17 00:00:00 2001 From: clueless <14300910+theClueless@users.noreply.github.com> Date: Sat, 22 Feb 2020 11:02:07 +0200 Subject: [PATCH 04/20] create query builder and re-enable tests. make the plugin manager plugin data the source for disabled plugins --- Plugins/Wox.Plugin.PluginIndicator/Main.cs | 3 +- Wox.Core/Plugin/PluginManager.cs | 31 +---------- Wox.Core/Plugin/QueryBuilder.cs | 50 ++++++++++++++++++ Wox.Core/Wox.Core.csproj | 1 + .../UserSettings/PluginSettings.cs | 8 ++- Wox.Test/QueryBuilderTest.cs | 51 +++++++++++++++++++ Wox.Test/QueryTest.cs | 33 ------------ Wox.Test/Wox.Test.csproj | 2 +- Wox/SettingWindow.xaml.cs | 3 +- Wox/ViewModel/MainViewModel.cs | 5 +- Wox/ViewModel/SettingWindowViewModel.cs | 25 ++------- 11 files changed, 120 insertions(+), 92 deletions(-) create mode 100644 Wox.Core/Plugin/QueryBuilder.cs create mode 100644 Wox.Test/QueryBuilderTest.cs delete mode 100644 Wox.Test/QueryTest.cs diff --git a/Plugins/Wox.Plugin.PluginIndicator/Main.cs b/Plugins/Wox.Plugin.PluginIndicator/Main.cs index 5f9ec07be..54dcf007a 100644 --- a/Plugins/Wox.Plugin.PluginIndicator/Main.cs +++ b/Plugins/Wox.Plugin.PluginIndicator/Main.cs @@ -13,8 +13,7 @@ namespace Wox.Plugin.PluginIndicator var results = from keyword in PluginManager.NonGlobalPlugins.Keys where keyword.StartsWith(query.Terms[0]) let metadata = PluginManager.NonGlobalPlugins[keyword].Metadata - let disabled = PluginManager.Settings.Plugins[metadata.ID].Disabled - where !disabled + where !metadata.Disabled select new Result { Title = keyword, diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index 27e2d4851..0166690b7 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -120,7 +120,7 @@ namespace Wox.Core.Plugin catch (Exception e) { Log.Exception(nameof(PluginManager), $"Fail to Init plugin: {pair.Metadata.Name}", e); - pair.Metadata.Disabled = true; // TODO: not sure this really disable it later on + pair.Metadata.Disabled = true; failedPlugins.Enqueue(pair); } }); @@ -149,35 +149,6 @@ namespace Wox.Core.Plugin PluginInstaller.Install(path); } - public static Query QueryInit(string text) //todo is that possible to move it into type Query? - { - // replace multiple white spaces with one white space - var terms = text.Split(new[] { Query.TermSeperater }, StringSplitOptions.RemoveEmptyEntries); - var rawQuery = string.Join(Query.TermSeperater, terms); - var actionKeyword = string.Empty; - var search = rawQuery; - var actionParameters = terms.ToList(); - if (terms.Length == 0) return null; - if (NonGlobalPlugins.ContainsKey(terms[0]) && - !Settings.Plugins[NonGlobalPlugins[terms[0]].Metadata.ID].Disabled) - { - actionKeyword = terms[0]; - actionParameters = terms.Skip(1).ToList(); - search = string.Join(Query.TermSeperater, actionParameters.ToArray()); - } - var query = new Query - { - Terms = terms, - RawQuery = rawQuery, - ActionKeyword = actionKeyword, - Search = search, - // Obsolete value initialisation - ActionName = actionKeyword, - ActionParameters = actionParameters - }; - return query; - } - public static List ValidPluginsForQuery(Query query) { if (NonGlobalPlugins.ContainsKey(query.ActionKeyword)) diff --git a/Wox.Core/Plugin/QueryBuilder.cs b/Wox.Core/Plugin/QueryBuilder.cs new file mode 100644 index 000000000..b8ac41988 --- /dev/null +++ b/Wox.Core/Plugin/QueryBuilder.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Wox.Plugin; + +namespace Wox.Core.Plugin +{ + public static class QueryBuilder + { + public static Query Build(string text, Dictionary nonGlobalPlugins) + { + // replace multiple white spaces with one white space + var terms = text.Split(new[] { Query.TermSeperater }, StringSplitOptions.RemoveEmptyEntries); + if (terms.Length == 0) + { // nothing was typed + return null; + } + + var rawQuery = string.Join(Query.TermSeperater, terms); + string actionKeyword, search; + string possibleActionKeyword = terms[0]; + List actionParameters; + if (nonGlobalPlugins.TryGetValue(possibleActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled) + { // use non global plugin for query + actionKeyword = possibleActionKeyword; + actionParameters = terms.Skip(1).ToList(); + search = rawQuery.Substring(actionKeyword.Length + 1); + } + else + { // non action keyword + actionKeyword = string.Empty; + actionParameters = terms.ToList(); + search = rawQuery; + } + + var query = new Query + { + Terms = terms, + RawQuery = rawQuery, + ActionKeyword = actionKeyword, + Search = search, + // Obsolete value initialisation + ActionName = actionKeyword, + ActionParameters = actionParameters + }; + + return query; + } + } +} \ No newline at end of file diff --git a/Wox.Core/Wox.Core.csproj b/Wox.Core/Wox.Core.csproj index c1758fdb3..bb5fbdc3c 100644 --- a/Wox.Core/Wox.Core.csproj +++ b/Wox.Core/Wox.Core.csproj @@ -53,6 +53,7 @@ + diff --git a/Wox.Infrastructure/UserSettings/PluginSettings.cs b/Wox.Infrastructure/UserSettings/PluginSettings.cs index c47fe7c15..346d98e53 100644 --- a/Wox.Infrastructure/UserSettings/PluginSettings.cs +++ b/Wox.Infrastructure/UserSettings/PluginSettings.cs @@ -28,7 +28,7 @@ namespace Wox.Infrastructure.UserSettings { ID = metadata.ID, Name = metadata.Name, - ActionKeywords = metadata.ActionKeywords, + ActionKeywords = metadata.ActionKeywords, Disabled = metadata.Disabled }; } @@ -39,7 +39,11 @@ namespace Wox.Infrastructure.UserSettings { public string ID { get; set; } public string Name { get; set; } - public List ActionKeywords { get; set; } + public List ActionKeywords { get; set; } // a reference of the action keywords from plugin manager + + /// + /// Used only to save the state of the plugin in settings + /// public bool Disabled { get; set; } } } diff --git a/Wox.Test/QueryBuilderTest.cs b/Wox.Test/QueryBuilderTest.cs new file mode 100644 index 000000000..0402d2ae8 --- /dev/null +++ b/Wox.Test/QueryBuilderTest.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using NUnit.Framework; +using Wox.Core.Plugin; +using Wox.Plugin; + +namespace Wox.Test +{ + public class QueryBuilderTest + { + [Test] + public void ExclusivePluginQueryTest() + { + var nonGlobalPlugins = new Dictionary + { + {">", new PluginPair {Metadata = new PluginMetadata {ActionKeywords = new List {">"}}}} + }; + + Query q = QueryBuilder.Build("> file.txt file2 file3", nonGlobalPlugins); + + Assert.AreEqual("file.txt file2 file3", q.Search); + Assert.AreEqual(">", q.ActionKeyword); + } + + [Test] + public void ExclusivePluginQueryIgnoreDisabledTest() + { + var nonGlobalPlugins = new Dictionary + { + {">", new PluginPair {Metadata = new PluginMetadata {ActionKeywords = new List {">"}, Disabled = true}}} + }; + + Query q = QueryBuilder.Build("> file.txt file2 file3", nonGlobalPlugins); + + Assert.AreEqual("> file.txt file2 file3", q.Search); + } + + [Test] + public void GenericPluginQueryTest() + { + Query q = QueryBuilder.Build("file.txt file2 file3", new Dictionary()); + + Assert.AreEqual("file.txt file2 file3", q.Search); + Assert.AreEqual("", q.ActionKeyword); + + Assert.AreEqual("file.txt", q.FirstSearch); + Assert.AreEqual("file2", q.SecondSearch); + Assert.AreEqual("file3", q.ThirdSearch); + Assert.AreEqual("file2 file3", q.SecondToEndSearch); + } + } +} diff --git a/Wox.Test/QueryTest.cs b/Wox.Test/QueryTest.cs deleted file mode 100644 index b7a0917ef..000000000 --- a/Wox.Test/QueryTest.cs +++ /dev/null @@ -1,33 +0,0 @@ -using NUnit.Framework; -using Wox.Core.Plugin; -using Wox.Plugin; - -namespace Wox.Test -{ - public class QueryTest - { - [Test] - [Ignore("Current query is tightly integrated with GUI, can't be tested.")] - public void ExclusivePluginQueryTest() - { - Query q = PluginManager.QueryInit("> file.txt file2 file3"); - - Assert.AreEqual(q.FirstSearch, "file.txt"); - Assert.AreEqual(q.SecondSearch, "file2"); - Assert.AreEqual(q.ThirdSearch, "file3"); - Assert.AreEqual(q.SecondToEndSearch, "file2 file3"); - } - - [Test] - [Ignore("Current query is tightly integrated with GUI, can't be tested.")] - public void GenericPluginQueryTest() - { - Query q = PluginManager.QueryInit("file.txt file2 file3"); - - Assert.AreEqual(q.FirstSearch, "file.txt"); - Assert.AreEqual(q.SecondSearch, "file2"); - Assert.AreEqual(q.ThirdSearch, "file3"); - Assert.AreEqual(q.SecondToEndSearch, "file2 file3"); - } - } -} diff --git a/Wox.Test/Wox.Test.csproj b/Wox.Test/Wox.Test.csproj index 7a3ef1f0c..2b1e6a78a 100644 --- a/Wox.Test/Wox.Test.csproj +++ b/Wox.Test/Wox.Test.csproj @@ -45,7 +45,7 @@ - + diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index 67d67351e..52addf362 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -215,7 +215,8 @@ namespace Wox private void OnPluginToggled(object sender, RoutedEventArgs e) { var id = _viewModel.SelectedPlugin.PluginPair.Metadata.ID; - _settings.PluginSettings.Plugins[id].Disabled = _viewModel.SelectedPlugin.PluginPair.Metadata.Disabled; + // used to sync the current status from the plugin manager into the setting to keep consistency after save + _settings.PluginSettings.Plugins[id].Disabled = _viewModel.SelectedPlugin.PluginPair.Metadata.Disabled; } private void OnPluginActionKeywordsClick(object sender, MouseButtonEventArgs e) diff --git a/Wox/ViewModel/MainViewModel.cs b/Wox/ViewModel/MainViewModel.cs index bd1314a27..acdd7c040 100644 --- a/Wox/ViewModel/MainViewModel.cs +++ b/Wox/ViewModel/MainViewModel.cs @@ -377,7 +377,7 @@ namespace Wox.ViewModel ProgressBarVisibility = Visibility.Hidden; _isQueryRunning = true; - var query = PluginManager.QueryInit(QueryText.Trim()); + var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins); if (query != null) { // handle the exclusiveness of plugin using action keyword @@ -401,8 +401,7 @@ namespace Wox.ViewModel { Parallel.ForEach(plugins, parallelOptions, plugin => { - var config = _settings.PluginSettings.Plugins[plugin.Metadata.ID]; - if (!config.Disabled) + if (!plugin.Metadata.Disabled) { var results = PluginManager.QueryForPlugin(plugin, query); UpdateResultView(results, plugin.Metadata, query); diff --git a/Wox/ViewModel/SettingWindowViewModel.cs b/Wox/ViewModel/SettingWindowViewModel.cs index 923e456b0..ce2c10a20 100644 --- a/Wox/ViewModel/SettingWindowViewModel.cs +++ b/Wox/ViewModel/SettingWindowViewModel.cs @@ -150,26 +150,11 @@ namespace Wox.ViewModel { get { - var plugins = PluginManager.AllPlugins; - var settings = Settings.PluginSettings.Plugins; - plugins.Sort((a, b) => - { - var d1 = settings[a.Metadata.ID].Disabled; - var d2 = settings[b.Metadata.ID].Disabled; - if (d1 == d2) - { - return string.Compare(a.Metadata.Name, b.Metadata.Name, StringComparison.CurrentCulture); - } - else - { - return d1.CompareTo(d2); - } - }); - - var metadatas = plugins.Select(p => new PluginViewModel - { - PluginPair = p, - }).ToList(); + var metadatas = PluginManager.AllPlugins + .OrderBy(x => x.Metadata.Disabled) + .ThenBy(y => y.Metadata.Name) + .Select(p => new PluginViewModel { PluginPair = p}) + .ToList(); return metadatas; } } From cecb65cd406bc32b8d50296812eed3255062c515 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 25 Feb 2020 21:08:51 +1100 Subject: [PATCH 05/20] Installed & portable mode: Enhance auto updates (#142) * Add handling of portable mode when updating Additionally: 1. Changed getting version from internally rather than from RELEASES file 2. Added PortableDataPath as a constant so can be used to determine if portable mode is used * Fix incorrectly wired auto update event handler * Fix Sys plugin missing Shutdown command icon * Add check update command to Sys plugin * Add message if current Wox version is latest * Add default silent when auto checking updates in background Silent when current is still the latest version * Move UserData folder to new version location * Changes per review 1. Move IsPortableMode to Constant 2. Merge if statement * Per comment- change variables to be more descriptive UpdateInfo and UpdateManager renamed * Per comment- Add exception handling and message if failed. --- Plugins/Wox.Plugin.Sys/Images/checkupdate.png | Bin 0 -> 23216 bytes Plugins/Wox.Plugin.Sys/Main.cs | 14 +++ Plugins/Wox.Plugin.Sys/Wox.Plugin.Sys.csproj | 6 ++ Wox.Core/Updater.cs | 81 ++++++++------ Wox.Infrastructure/Wox.cs | 22 ++-- Wox.Plugin/IPublicAPI.cs | 5 + Wox.Plugin/SharedCommands/FilesFolders.cs | 101 ++++++++++++++++++ Wox.Plugin/Wox.Plugin.csproj | 1 + Wox/PublicAPIInstance.cs | 6 ++ Wox/SettingWindow.xaml | 6 +- Wox/ViewModel/SettingWindowViewModel.cs | 2 +- 11 files changed, 201 insertions(+), 43 deletions(-) create mode 100644 Plugins/Wox.Plugin.Sys/Images/checkupdate.png create mode 100644 Wox.Plugin/SharedCommands/FilesFolders.cs diff --git a/Plugins/Wox.Plugin.Sys/Images/checkupdate.png b/Plugins/Wox.Plugin.Sys/Images/checkupdate.png new file mode 100644 index 0000000000000000000000000000000000000000..955f6fdbb7be9c75a03961cf065679a5b698f978 GIT binary patch literal 23216 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%0Dvx=x8MNt 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 literal 0 HcmV?d00001 diff --git a/Plugins/Wox.Plugin.Sys/Main.cs b/Plugins/Wox.Plugin.Sys/Main.cs index e888dbb37..f6be3a435 100644 --- a/Plugins/Wox.Plugin.Sys/Main.cs +++ b/Plugins/Wox.Plugin.Sys/Main.cs @@ -234,6 +234,20 @@ namespace Wox.Plugin.Sys context.API.GetTranslation("wox_plugin_sys_dlgtext_all_applicableplugins_reloaded")); return true; } + }, + new Result + { + Title = "Check For Update", + SubTitle = "Check for new Wox update", + IcoPath = "Images\\checkupdate.png", + Action = c => + { + Application.Current.MainWindow.Hide(); + context.API.CheckForNewUpdate(); + context.API.ShowMsg("Please wait...", + "Checking for new update"); + return true; + } } }); return results; diff --git a/Plugins/Wox.Plugin.Sys/Wox.Plugin.Sys.csproj b/Plugins/Wox.Plugin.Sys/Wox.Plugin.Sys.csproj index 09a1e761f..ffdfa5972 100644 --- a/Plugins/Wox.Plugin.Sys/Wox.Plugin.Sys.csproj +++ b/Plugins/Wox.Plugin.Sys/Wox.Plugin.Sys.csproj @@ -71,9 +71,15 @@ + + PreserveNewest + PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Wox.Core/Updater.cs b/Wox.Core/Updater.cs index 971995f5e..9262d78f4 100644 --- a/Wox.Core/Updater.cs +++ b/Wox.Core/Updater.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Net; using System.Net.Http; @@ -10,9 +10,11 @@ using JetBrains.Annotations; using Squirrel; using Newtonsoft.Json; using Wox.Core.Resource; +using Wox.Plugin.SharedCommands; using Wox.Infrastructure; using Wox.Infrastructure.Http; using Wox.Infrastructure.Logger; +using System.IO; namespace Wox.Core { @@ -25,14 +27,14 @@ namespace Wox.Core GitHubRepository = gitHubRepository; } - public async Task UpdateApp() + public async Task UpdateApp(bool silentIfLatestVersion = true) { - UpdateManager m; - UpdateInfo u; + UpdateManager updateManager; + UpdateInfo newUpdateInfo; try { - m = await GitHubUpdateManager(GitHubRepository); + updateManager = await GitHubUpdateManager(GitHubRepository); } catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException) { @@ -43,42 +45,61 @@ namespace Wox.Core try { // UpdateApp CheckForUpdate will return value only if the app is squirrel installed - u = await m.CheckForUpdate().NonNull(); + newUpdateInfo = await updateManager.CheckForUpdate().NonNull(); } catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException) { Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to api.github.com.", e); - m.Dispose(); + updateManager.Dispose(); return; } - var fr = u.FutureReleaseEntry; - var cr = u.CurrentlyInstalledVersion; - Log.Info($"|Updater.UpdateApp|Future Release <{fr.Formatted()}>"); - if (fr.Version > cr.Version) + var newReleaseVersion = Version.Parse(newUpdateInfo.FutureReleaseEntry.Version.ToString()); + var currentVersion = Version.Parse(Constant.Version); + + Log.Info($"|Updater.UpdateApp|Future Release <{newUpdateInfo.FutureReleaseEntry.Formatted()}>"); + + if (newReleaseVersion <= currentVersion) { - try - { - await m.DownloadReleases(u.ReleasesToApply); - } - catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException) - { - Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e); - m.Dispose(); - return; - } - - await m.ApplyReleases(u); - await m.CreateUninstallerRegistryEntry(); - - var newVersionTips = this.NewVersinoTips(fr.Version.ToString()); - - MessageBox.Show(newVersionTips); - Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}"); + if (!silentIfLatestVersion) + MessageBox.Show("You already have the latest Wox version"); + updateManager.Dispose(); + return; } + try + { + await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply); + } + catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException) + { + Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e); + updateManager.Dispose(); + return; + } + + await updateManager.ApplyReleases(newUpdateInfo); + + if (Constant.IsPortableMode) + { + var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{Constant.PortableFolderName}"; + FilesFolders.Copy(Constant.PortableDataPath, targetDestination); + if (!FilesFolders.VerifyBothFolderFilesEqual(Constant.PortableDataPath, targetDestination)) + MessageBox.Show(string.Format("Wox was not able to move your user profile data to the new update version. Please manually" + + "move your profile data folder from {0} to {1}", Constant.PortableDataPath, targetDestination)); + } + else + { + await updateManager.CreateUninstallerRegistryEntry(); + } + + var newVersionTips = NewVersinoTips(newReleaseVersion.ToString()); + + MessageBox.Show(newVersionTips); + Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}"); + // always dispose UpdateManager - m.Dispose(); + updateManager.Dispose(); } [UsedImplicitly] diff --git a/Wox.Infrastructure/Wox.cs b/Wox.Infrastructure/Wox.cs index 396ee0bb1..d09e7b904 100644 --- a/Wox.Infrastructure/Wox.cs +++ b/Wox.Infrastructure/Wox.cs @@ -7,12 +7,22 @@ namespace Wox.Infrastructure { public static class Constant { + public const string Wox = "Wox"; + public const string Plugins = "Plugins"; + + private static readonly Assembly Assembly = Assembly.GetExecutingAssembly(); + public static readonly string ProgramDirectory = Directory.GetParent(Assembly.Location.NonNull()).ToString(); + public static readonly string ExecutablePath = Path.Combine(ProgramDirectory, Wox + ".exe"); + + public static bool IsPortableMode; + public const string PortableFolderName = "UserData"; + public static string PortableDataPath = Path.Combine(ProgramDirectory, PortableFolderName); public static string DetermineDataDirectory() { - string portableDataPath = Path.Combine(ProgramDirectory, "UserData"); - if (Directory.Exists(portableDataPath)) + if (Directory.Exists(PortableDataPath)) { - return portableDataPath; + IsPortableMode = true; + return PortableDataPath; } else { @@ -20,12 +30,6 @@ namespace Wox.Infrastructure } } - public const string Wox = "Wox"; - public const string Plugins = "Plugins"; - - private static readonly Assembly Assembly = Assembly.GetExecutingAssembly(); - public static readonly string ProgramDirectory = Directory.GetParent(Assembly.Location.NonNull()).ToString(); - public static readonly string ExecutablePath = Path.Combine(ProgramDirectory, Wox + ".exe"); public static readonly string DataDirectory = DetermineDataDirectory(); public static readonly string PluginsDirectory = Path.Combine(DataDirectory, Plugins); public static readonly string PreinstalledDirectory = Path.Combine(ProgramDirectory, Plugins); diff --git a/Wox.Plugin/IPublicAPI.cs b/Wox.Plugin/IPublicAPI.cs index 8dc838963..754b76d36 100644 --- a/Wox.Plugin/IPublicAPI.cs +++ b/Wox.Plugin/IPublicAPI.cs @@ -70,6 +70,11 @@ namespace Wox.Plugin /// void ReloadAllPluginData(); + /// + /// Check for new Wox update + /// + void CheckForNewUpdate(); + /// /// Show message box /// diff --git a/Wox.Plugin/SharedCommands/FilesFolders.cs b/Wox.Plugin/SharedCommands/FilesFolders.cs new file mode 100644 index 000000000..584a83bc6 --- /dev/null +++ b/Wox.Plugin/SharedCommands/FilesFolders.cs @@ -0,0 +1,101 @@ +using System; +using System.IO; +using System.Windows; + +namespace Wox.Plugin.SharedCommands +{ + public static class FilesFolders + { + public static void Copy(this string sourcePath, string targetPath) + { + // Get the subdirectories for the specified directory. + DirectoryInfo dir = new DirectoryInfo(sourcePath); + + if (!dir.Exists) + { + throw new DirectoryNotFoundException( + "Source directory does not exist or could not be found: " + + sourcePath); + } + + try + { + DirectoryInfo[] dirs = dir.GetDirectories(); + // If the destination directory doesn't exist, create it. + if (!Directory.Exists(targetPath)) + { + Directory.CreateDirectory(targetPath); + } + + // Get the files in the directory and copy them to the new location. + FileInfo[] files = dir.GetFiles(); + foreach (FileInfo file in files) + { + string temppath = Path.Combine(targetPath, file.Name); + file.CopyTo(temppath, false); + } + + // Recursively copy subdirectories by calling itself on each subdirectory until there are no more to copy + foreach (DirectoryInfo subdir in dirs) + { + string temppath = Path.Combine(targetPath, subdir.Name); + Copy(subdir.FullName, temppath); + } + } + catch (Exception e) + { +#if DEBUG + throw e; +#else + MessageBox.Show(string.Format("Copying path {0} has failed, it will now be deleted for consistency", targetPath)); + RemoveFolder(targetPath); +#endif + } + + } + + public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPath) + { + try + { + var fromDir = new DirectoryInfo(fromPath); + var toDir = new DirectoryInfo(toPath); + + if (fromDir.GetFiles("*", SearchOption.AllDirectories).Length != toDir.GetFiles("*", SearchOption.AllDirectories).Length) + return false; + + if (fromDir.GetDirectories("*", SearchOption.AllDirectories).Length != toDir.GetDirectories("*", SearchOption.AllDirectories).Length) + return false; + + return true; + } + catch (Exception e) + { +#if DEBUG + throw e; +#else + MessageBox.Show(string.Format("Unable to verify folders and files between {0} and {1}", fromPath, toPath)); + return false; +#endif + } + + } + + public static void RemoveFolder(this string path) + { + try + { + if (Directory.Exists(path)) + Directory.Delete(path, true); + } + catch (Exception e) + { +#if DEBUG + throw e; +#else + MessageBox.Show(string.Format("Not able to delete folder {0}, please go to the location and manually delete it", path)); +#endif + } + } + } +} diff --git a/Wox.Plugin/Wox.Plugin.csproj b/Wox.Plugin/Wox.Plugin.csproj index ceba2bbf0..b0b457e98 100644 --- a/Wox.Plugin/Wox.Plugin.csproj +++ b/Wox.Plugin/Wox.Plugin.csproj @@ -65,6 +65,7 @@ + diff --git a/Wox/PublicAPIInstance.cs b/Wox/PublicAPIInstance.cs index 314fc13b6..58915f87b 100644 --- a/Wox/PublicAPIInstance.cs +++ b/Wox/PublicAPIInstance.cs @@ -5,6 +5,7 @@ using System.Net; using System.Threading.Tasks; using System.Windows; using Squirrel; +using Wox.Core; using Wox.Core.Plugin; using Wox.Core.Resource; using Wox.Helper; @@ -65,6 +66,11 @@ namespace Wox UpdateManager.RestartApp(); } + public void CheckForNewUpdate() + { + _settingsVM.UpdateApp(); + } + public void SaveAppAllSettings() { _mainVM.Save(); diff --git a/Wox/SettingWindow.xaml b/Wox/SettingWindow.xaml index a6f23814f..1eddd8ab6 100644 --- a/Wox/SettingWindow.xaml +++ b/Wox/SettingWindow.xaml @@ -33,7 +33,8 @@ - + @@ -51,8 +52,7 @@ - + diff --git a/Wox/ViewModel/SettingWindowViewModel.cs b/Wox/ViewModel/SettingWindowViewModel.cs index 923e456b0..c93cdd413 100644 --- a/Wox/ViewModel/SettingWindowViewModel.cs +++ b/Wox/ViewModel/SettingWindowViewModel.cs @@ -44,7 +44,7 @@ namespace Wox.ViewModel public async void UpdateApp() { - await _updater.UpdateApp(); + await _updater.UpdateApp(false); } public void Save() From 2e714a8d7b91c9a73786389ac5903b2fa647f196 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Tue, 25 Feb 2020 17:38:47 +0100 Subject: [PATCH 06/20] Create localization helper classes --- Wox.Core/Resource/LocalizationConverter.cs | 37 +++++++++++++++++++ .../Resource/LocalizedDescriptionAttribute.cs | 27 ++++++++++++++ Wox.Core/Wox.Core.csproj | 2 + 3 files changed, 66 insertions(+) create mode 100644 Wox.Core/Resource/LocalizationConverter.cs create mode 100644 Wox.Core/Resource/LocalizedDescriptionAttribute.cs diff --git a/Wox.Core/Resource/LocalizationConverter.cs b/Wox.Core/Resource/LocalizationConverter.cs new file mode 100644 index 000000000..d86bf5f7e --- /dev/null +++ b/Wox.Core/Resource/LocalizationConverter.cs @@ -0,0 +1,37 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using System.Reflection; +using System.Windows.Data; + +namespace Wox.Core +{ + public class LocalizationConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (targetType == typeof(string) && value != null) + { + FieldInfo fi = value.GetType().GetField(value.ToString()); + if (fi != null) + { + string localizedDescription = string.Empty; + var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); + if ((attributes.Length > 0) && (!String.IsNullOrEmpty(attributes[0].Description))) + { + localizedDescription = attributes[0].Description; + } + + return (!String.IsNullOrEmpty(localizedDescription)) ? localizedDescription : value.ToString(); + } + } + + return string.Empty; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Wox.Core/Resource/LocalizedDescriptionAttribute.cs b/Wox.Core/Resource/LocalizedDescriptionAttribute.cs new file mode 100644 index 000000000..ef1257220 --- /dev/null +++ b/Wox.Core/Resource/LocalizedDescriptionAttribute.cs @@ -0,0 +1,27 @@ +using System.ComponentModel; +using Wox.Core.Resource; + +namespace Wox.Core +{ + public class LocalizedDescriptionAttribute : DescriptionAttribute + { + private readonly Internationalization _translator; + private readonly string _resourceKey; + + public LocalizedDescriptionAttribute(string resourceKey) + { + _translator = InternationalizationManager.Instance; + _resourceKey = resourceKey; + } + + public override string Description + { + get + { + string description = _translator.GetTranslation(_resourceKey); + return string.IsNullOrWhiteSpace(description) ? + string.Format("[[{0}]]", _resourceKey) : description; + } + } + } +} diff --git a/Wox.Core/Wox.Core.csproj b/Wox.Core/Wox.Core.csproj index 9d8f1e794..bec5a13a6 100644 --- a/Wox.Core/Wox.Core.csproj +++ b/Wox.Core/Wox.Core.csproj @@ -109,6 +109,8 @@ + + From 73a264b00d8cbbd58cc3f689e3ff22016e5f215e Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Tue, 25 Feb 2020 17:43:12 +0100 Subject: [PATCH 07/20] Create DecimalSeperator enum Localization is handled using the LocalizedDescription attribute and the LocalizationConverter. --- .../Wox.Plugin.Calculator/DecimalSeparator.cs | 24 +++++++++++++++++++ .../Wox.Plugin.Calculator/Languages/de.xaml | 5 +++- .../Wox.Plugin.Calculator/Languages/en.xaml | 5 +++- .../Wox.Plugin.Calculator.csproj | 5 +++- 4 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 Plugins/Wox.Plugin.Calculator/DecimalSeparator.cs diff --git a/Plugins/Wox.Plugin.Calculator/DecimalSeparator.cs b/Plugins/Wox.Plugin.Calculator/DecimalSeparator.cs new file mode 100644 index 000000000..5aad9b39a --- /dev/null +++ b/Plugins/Wox.Plugin.Calculator/DecimalSeparator.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Wox.Core; + +namespace Wox.Plugin.Caculator +{ + [TypeConverter(typeof(LocalizationConverter))] + public enum DecimalSeparator + { + [LocalizedDescription("wox_plugin_calculator_decimal_seperator_use_system_locale")] + UseSystemLocale, + + [LocalizedDescription("wox_plugin_calculator_decimal_seperator_dot")] + Dot, + + [LocalizedDescription("wox_plugin_calculator_decimal_seperator_comma")] + Comma + } +} \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Calculator/Languages/de.xaml b/Plugins/Wox.Plugin.Calculator/Languages/de.xaml index 286e4bc9b..1f550de84 100644 --- a/Plugins/Wox.Plugin.Calculator/Languages/de.xaml +++ b/Plugins/Wox.Plugin.Calculator/Languages/de.xaml @@ -1,4 +1,4 @@ - @@ -7,4 +7,7 @@ Keine Zahl (NaN) Ausdruck falsch oder nicht vollständig (Klammern vergessen?) Diese Zahl in die Zwischenablage kopieren + Systemeinstellung nutzen + Komma (,) + Punkt (.) \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Calculator/Languages/en.xaml b/Plugins/Wox.Plugin.Calculator/Languages/en.xaml index 3b5fa32b3..0de9225b3 100644 --- a/Plugins/Wox.Plugin.Calculator/Languages/en.xaml +++ b/Plugins/Wox.Plugin.Calculator/Languages/en.xaml @@ -1,4 +1,4 @@ - @@ -7,4 +7,7 @@ Not a number (NaN) Expression wrong or incomplete (Did you forget some parentheses?) Copy this number to the clipboard + Use system locale + Comma (,) + Dot (.) \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj b/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj index cf7ce1241..a257caed6 100644 --- a/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj +++ b/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj @@ -1,4 +1,4 @@ - + @@ -46,11 +46,14 @@ + + Properties\SolutionAssemblyInfo.cs + From b37669b77e50c937f84e2d211009428c696e0a53 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Tue, 25 Feb 2020 17:45:43 +0100 Subject: [PATCH 08/20] Create user control for Calculator settings --- .../Wox.Plugin.Calculator/Languages/de.xaml | 4 +- .../Wox.Plugin.Calculator/Languages/en.xaml | 4 +- Plugins/Wox.Plugin.Calculator/Settings.cs | 13 +++++ .../ViewModels/SettingsViewModel.cs | 28 +++++++++ .../Views/CalculatorSettings.xaml | 44 ++++++++++++++ .../Views/CalculatorSettings.xaml.cs | 42 ++++++++++++++ .../Wox.Plugin.Calculator.csproj | 17 +++++- Wox.Infrastructure/UI/EnumBindingSource.cs | 57 +++++++++++++++++++ Wox.Infrastructure/Wox.Infrastructure.csproj | 1 + 9 files changed, 207 insertions(+), 3 deletions(-) create mode 100644 Plugins/Wox.Plugin.Calculator/Settings.cs create mode 100644 Plugins/Wox.Plugin.Calculator/ViewModels/SettingsViewModel.cs create mode 100644 Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml create mode 100644 Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml.cs create mode 100644 Wox.Infrastructure/UI/EnumBindingSource.cs diff --git a/Plugins/Wox.Plugin.Calculator/Languages/de.xaml b/Plugins/Wox.Plugin.Calculator/Languages/de.xaml index 1f550de84..f5f1b27b5 100644 --- a/Plugins/Wox.Plugin.Calculator/Languages/de.xaml +++ b/Plugins/Wox.Plugin.Calculator/Languages/de.xaml @@ -1,4 +1,4 @@ - @@ -7,6 +7,8 @@ Keine Zahl (NaN) Ausdruck falsch oder nicht vollständig (Klammern vergessen?) Diese Zahl in die Zwischenablage kopieren + Dezimaltrennzeichen + Das Dezimaltrennzeichen, welches bei der Ausgabe verwendet werden soll. Systemeinstellung nutzen Komma (,) Punkt (.) diff --git a/Plugins/Wox.Plugin.Calculator/Languages/en.xaml b/Plugins/Wox.Plugin.Calculator/Languages/en.xaml index 0de9225b3..e214919d1 100644 --- a/Plugins/Wox.Plugin.Calculator/Languages/en.xaml +++ b/Plugins/Wox.Plugin.Calculator/Languages/en.xaml @@ -1,4 +1,4 @@ - @@ -7,6 +7,8 @@ Not a number (NaN) Expression wrong or incomplete (Did you forget some parentheses?) Copy this number to the clipboard + Decimal separator + The decimal separator to be used in the output. Use system locale Comma (,) Dot (.) diff --git a/Plugins/Wox.Plugin.Calculator/Settings.cs b/Plugins/Wox.Plugin.Calculator/Settings.cs new file mode 100644 index 000000000..a45405b29 --- /dev/null +++ b/Plugins/Wox.Plugin.Calculator/Settings.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Wox.Plugin.Caculator +{ + public class Settings + { + public DecimalSeparator DecimalSeparator { get; set; } = DecimalSeparator.UseSystemLocale; + } +} diff --git a/Plugins/Wox.Plugin.Calculator/ViewModels/SettingsViewModel.cs b/Plugins/Wox.Plugin.Calculator/ViewModels/SettingsViewModel.cs new file mode 100644 index 000000000..e06ad675c --- /dev/null +++ b/Plugins/Wox.Plugin.Calculator/ViewModels/SettingsViewModel.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Wox.Infrastructure.Storage; +using Wox.Infrastructure.UserSettings; + +namespace Wox.Plugin.Caculator.ViewModels +{ + public class SettingsViewModel : BaseModel, ISavable + { + private readonly PluginJsonStorage _storage; + + public SettingsViewModel() + { + _storage = new PluginJsonStorage(); + Settings = _storage.Load(); + } + + public Settings Settings { get; set; } + + public void Save() + { + _storage.Save(); + } + } +} diff --git a/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml new file mode 100644 index 000000000..b9404710d --- /dev/null +++ b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml.cs b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml.cs new file mode 100644 index 000000000..c002243c5 --- /dev/null +++ b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Wox.Plugin.Caculator.ViewModels; + +namespace Wox.Plugin.Caculator.Views +{ + /// + /// Interaction logic for CalculatorSettings.xaml + /// + public partial class CalculatorSettings : UserControl + { + private SettingsViewModel _viewModel; + private Settings _settings; + + public CalculatorSettings(SettingsViewModel viewModel) + { + _viewModel = viewModel; + _settings = viewModel.Settings; + DataContext = viewModel; + InitializeComponent(); + } + + private void CalculatorSettings_Loaded(object sender, RoutedEventArgs e) + { + DecimalSeparatorComboBox.SelectedItem = _settings.DecimalSeparator; + } + } + + +} diff --git a/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj b/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj index a257caed6..4f7590273 100644 --- a/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj +++ b/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj @@ -1,4 +1,4 @@ - + @@ -57,6 +57,11 @@ + + + + CalculatorSettings.xaml + @@ -65,6 +70,10 @@ + + {B749F0DB-8E75-47DB-9E5E-265D16D0C0D2} + Wox.Core + {4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} Wox.Infrastructure @@ -121,6 +130,12 @@ PreserveNewest + + + Designer + MSBuild:Compile + + diff --git a/Wox.Infrastructure/UI/EnumBindingSource.cs b/Wox.Infrastructure/UI/EnumBindingSource.cs new file mode 100644 index 000000000..c23aacd81 --- /dev/null +++ b/Wox.Infrastructure/UI/EnumBindingSource.cs @@ -0,0 +1,57 @@ +using System; +using System.Windows.Markup; + +namespace Wox.Infrastructure.UI +{ + public class EnumBindingSourceExtension : MarkupExtension + { + private Type _enumType; + public Type EnumType + { + get { return _enumType; } + set + { + if (value != _enumType) + { + if (value != null) + { + Type enumType = Nullable.GetUnderlyingType(value) ?? value; + if (!enumType.IsEnum) + { + throw new ArgumentException("Type must represent an enum."); + } + } + + _enumType = value; + } + } + } + + public EnumBindingSourceExtension() { } + + public EnumBindingSourceExtension(Type enumType) + { + EnumType = enumType; + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + if (_enumType == null) + { + throw new InvalidOperationException("The EnumType must be specified."); + } + + Type actualEnumType = Nullable.GetUnderlyingType(_enumType) ?? _enumType; + Array enumValues = Enum.GetValues(actualEnumType); + + if (actualEnumType == _enumType) + { + return enumValues; + } + + Array tempArray = Array.CreateInstance(actualEnumType, enumValues.Length + 1); + enumValues.CopyTo(tempArray, 1); + return tempArray; + } + } +} diff --git a/Wox.Infrastructure/Wox.Infrastructure.csproj b/Wox.Infrastructure/Wox.Infrastructure.csproj index af76894ed..ab8976fb8 100644 --- a/Wox.Infrastructure/Wox.Infrastructure.csproj +++ b/Wox.Infrastructure/Wox.Infrastructure.csproj @@ -87,6 +87,7 @@ + From 3d3d9435dc35201f4e17c92dc5e2e156cb284375 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Tue, 25 Feb 2020 17:48:18 +0100 Subject: [PATCH 09/20] Set minimum expression lenght to 2 Calculations like 8! haven't been possible before due to a validation on the minimum query lenght. --- Plugins/Wox.Plugin.Calculator/Main.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Plugins/Wox.Plugin.Calculator/Main.cs b/Plugins/Wox.Plugin.Calculator/Main.cs index c8c7fcb0b..113240c5e 100644 --- a/Plugins/Wox.Plugin.Calculator/Main.cs +++ b/Plugins/Wox.Plugin.Calculator/Main.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows; @@ -29,9 +29,12 @@ namespace Wox.Plugin.Caculator public List Query(Query query) { // Don't affect when user only input "e" or "i" keyword - if (query.Search.Length <= 2 + if (query.Search.Length < 2 || !RegValidExpressChar.IsMatch(query.Search) - || !IsBracketComplete(query.Search)) return new List(); + || !IsBracketComplete(query.Search)) + { + return new List(); + } try { From 570c1d9a5f027d12fde127966b9bda083aa916e8 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Tue, 25 Feb 2020 17:50:50 +0100 Subject: [PATCH 10/20] Integrate calculator settings Save & load settings when plugin is in use & specify user control. --- Plugins/Wox.Plugin.Calculator/Main.cs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Plugins/Wox.Plugin.Calculator/Main.cs b/Plugins/Wox.Plugin.Calculator/Main.cs index 113240c5e..9ebdd36c1 100644 --- a/Plugins/Wox.Plugin.Calculator/Main.cs +++ b/Plugins/Wox.Plugin.Calculator/Main.cs @@ -2,11 +2,15 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows; +using System.Windows.Controls; using Mages.Core; +using Wox.Infrastructure.Storage; +using Wox.Plugin.Caculator.ViewModels; +using Wox.Plugin.Caculator.Views; namespace Wox.Plugin.Caculator { - public class Main : IPlugin, IPluginI18n + public class Main : IPlugin, IPluginI18n, ISavable, ISettingProvider { private static readonly Regex RegValidExpressChar = new Regex( @"^(" + @@ -21,11 +25,22 @@ namespace Wox.Plugin.Caculator private static readonly Engine MagesEngine; private PluginInitContext Context { get; set; } + private static Settings _settings; + private static SettingsViewModel _viewModel; + static Main() { MagesEngine = new Engine(); } + public void Init(PluginInitContext context) + { + Context = context; + + _viewModel = new SettingsViewModel(); + _settings = _viewModel.Settings; + } + public List Query(Query query) { // Don't affect when user only input "e" or "i" keyword @@ -115,5 +130,15 @@ namespace Wox.Plugin.Caculator { return Context.API.GetTranslation("wox_plugin_caculator_plugin_description"); } + + public Control CreateSettingPanel() + { + return new CalculatorSettings(_viewModel); + } + + public void Save() + { + _viewModel.Save(); + } } } From 5ae3262279f13df92c3a0dda6e3602abefd2cad8 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Tue, 25 Feb 2020 17:53:18 +0100 Subject: [PATCH 11/20] Adjust decimal separator based on setting The output decimal separator selected will be used for the output. The input can also handle comma and dot as separator now. --- Plugins/Wox.Plugin.Calculator/Main.cs | 41 ++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/Plugins/Wox.Plugin.Calculator/Main.cs b/Plugins/Wox.Plugin.Calculator/Main.cs index 9ebdd36c1..78ccfcac6 100644 --- a/Plugins/Wox.Plugin.Calculator/Main.cs +++ b/Plugins/Wox.Plugin.Calculator/Main.cs @@ -64,11 +64,12 @@ namespace Wox.Plugin.Caculator if (!string.IsNullOrEmpty(result?.ToString())) { + string newResult = ChangeDecimalSeparator(result, GetDecimalSeparator()); return new List { new Result { - Title = result.ToString(), + Title = newResult, IcoPath = "Images/calculator.png", Score = 300, SubTitle = Context.API.GetTranslation("wox_plugin_calculator_copy_number_to_clipboard"), @@ -76,7 +77,7 @@ namespace Wox.Plugin.Caculator { try { - Clipboard.SetText(result.ToString()); + Clipboard.SetText(newResult); return true; } catch (ExternalException) @@ -97,6 +98,37 @@ namespace Wox.Plugin.Caculator return new List(); } + private string ChangeDecimalSeparator(object value, string newDecimalSeparator) + { + if (value == null || String.IsNullOrEmpty(value.ToString())) + { + return string.Empty; + } + + if (String.IsNullOrEmpty(newDecimalSeparator)) + { + return value.ToString(); + } + + var numberFormatInfo = new NumberFormatInfo + { + NumberDecimalSeparator = newDecimalSeparator + }; + return Convert.ToDecimal(value).ToString(numberFormatInfo); + } + + private string GetDecimalSeparator() + { + string systemDecimalSeperator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator; + switch (_settings.DecimalSeparator) + { + case DecimalSeparator.UseSystemLocale: return systemDecimalSeperator; + case DecimalSeparator.Dot: return "."; + case DecimalSeparator.Comma: return ","; + default: return systemDecimalSeperator; + } + } + private bool IsBracketComplete(string query) { var matchs = RegBrackets.Matches(query); @@ -116,11 +148,6 @@ namespace Wox.Plugin.Caculator return leftBracketCount == 0; } - public void Init(PluginInitContext context) - { - Context = context; - } - public string GetTranslatedPluginTitle() { return Context.API.GetTranslation("wox_plugin_caculator_plugin_name"); From 4f4e423a4bf3e7880f58361a33c816db2f376a3c Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Tue, 25 Feb 2020 17:55:04 +0100 Subject: [PATCH 12/20] Add missing using directives --- Plugins/Wox.Plugin.Calculator/Main.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Plugins/Wox.Plugin.Calculator/Main.cs b/Plugins/Wox.Plugin.Calculator/Main.cs index 78ccfcac6..db3016fad 100644 --- a/Plugins/Wox.Plugin.Calculator/Main.cs +++ b/Plugins/Wox.Plugin.Calculator/Main.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Generic; +using System.Globalization; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows; @@ -30,9 +32,9 @@ namespace Wox.Plugin.Caculator static Main() { - MagesEngine = new Engine(); + MagesEngine = new Engine(); } - + public void Init(PluginInitContext context) { Context = context; @@ -147,7 +149,7 @@ namespace Wox.Plugin.Caculator return leftBracketCount == 0; } - + public string GetTranslatedPluginTitle() { return Context.API.GetTranslation("wox_plugin_caculator_plugin_name"); From 3d917e02581ffc6df6c5449d7c1344071230f899 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Wed, 26 Feb 2020 19:40:20 +0100 Subject: [PATCH 13/20] Extract validation to method --- Plugins/Wox.Plugin.Calculator/Main.cs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Plugins/Wox.Plugin.Calculator/Main.cs b/Plugins/Wox.Plugin.Calculator/Main.cs index db3016fad..5d7b347d1 100644 --- a/Plugins/Wox.Plugin.Calculator/Main.cs +++ b/Plugins/Wox.Plugin.Calculator/Main.cs @@ -45,10 +45,7 @@ namespace Wox.Plugin.Caculator public List Query(Query query) { - // Don't affect when user only input "e" or "i" keyword - if (query.Search.Length < 2 - || !RegValidExpressChar.IsMatch(query.Search) - || !IsBracketComplete(query.Search)) + if (!CanCalculate(query)) { return new List(); } @@ -100,6 +97,27 @@ namespace Wox.Plugin.Caculator return new List(); } + private bool CanCalculate(Query query) + { + // Don't execute when user only input "e" or "i" keyword + if (query.Search.Length < 2) + { + return false; + } + + if (!RegValidExpressChar.IsMatch(query.Search)) + { + return false; + } + + if (!IsBracketComplete(query.Search)) + { + return false; + } + + return true; + } + private string ChangeDecimalSeparator(object value, string newDecimalSeparator) { if (value == null || String.IsNullOrEmpty(value.ToString())) From 54191d6d88bb812aeb6c46228d3f0a61f855b568 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Wed, 26 Feb 2020 20:00:07 +0100 Subject: [PATCH 14/20] Replace static text with localized label --- .../Views/CalculatorSettings.xaml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml index b9404710d..a02fdffec 100644 --- a/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml +++ b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml @@ -26,13 +26,14 @@ - + + Grid.Row="0" + x:Name="DecimalSeparatorComboBox" + Width="200" + HorizontalAlignment="Left" + SelectedItem="{Binding Settings.DecimalSeparator}" + ItemsSource="{Binding Source={ui:EnumBindingSource {x:Type calculator:DecimalSeparator}}}"> From f18256ab398e480e203cd9b8ae9c7e99459af224 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Wed, 26 Feb 2020 20:46:27 +0100 Subject: [PATCH 15/20] Add "Max. decimal places" setting --- Plugins/Wox.Plugin.Calculator/Settings.cs | 1 + .../ViewModels/SettingsViewModel.cs | 2 ++ .../Views/CalculatorSettings.xaml | 25 +++++++++++++------ .../Views/CalculatorSettings.xaml.cs | 5 ++-- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Plugins/Wox.Plugin.Calculator/Settings.cs b/Plugins/Wox.Plugin.Calculator/Settings.cs index a45405b29..ce01f2da0 100644 --- a/Plugins/Wox.Plugin.Calculator/Settings.cs +++ b/Plugins/Wox.Plugin.Calculator/Settings.cs @@ -9,5 +9,6 @@ namespace Wox.Plugin.Caculator public class Settings { public DecimalSeparator DecimalSeparator { get; set; } = DecimalSeparator.UseSystemLocale; + public int MaxDecimalPlaces { get; set; } = 10; } } diff --git a/Plugins/Wox.Plugin.Calculator/ViewModels/SettingsViewModel.cs b/Plugins/Wox.Plugin.Calculator/ViewModels/SettingsViewModel.cs index e06ad675c..8550f47a5 100644 --- a/Plugins/Wox.Plugin.Calculator/ViewModels/SettingsViewModel.cs +++ b/Plugins/Wox.Plugin.Calculator/ViewModels/SettingsViewModel.cs @@ -20,6 +20,8 @@ namespace Wox.Plugin.Caculator.ViewModels public Settings Settings { get; set; } + public IEnumerable MaxDecimalPlacesRange => Enumerable.Range(1, 20); + public void Save() { _storage.Save(); diff --git a/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml index a02fdffec..0cb21c550 100644 --- a/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml +++ b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml @@ -3,11 +3,10 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:local="clr-namespace:Wox.Plugin.Caculator.Views" - xmlns:infrastructure="clr-namespace:Wox.Infrastructure;assembly=Wox.Infrastructure" xmlns:ui="clr-namespace:Wox.Infrastructure.UI;assembly=Wox.Infrastructure" xmlns:calculator="clr-namespace:Wox.Plugin.Caculator" xmlns:core="clr-namespace:Wox.Core;assembly=Wox.Core" + xmlns:viewModels="clr-namespace:Wox.Plugin.Caculator.ViewModels" mc:Ignorable="d" Loaded="CalculatorSettings_Loaded" d:DesignHeight="450" d:DesignWidth="800"> @@ -19,18 +18,19 @@ - + + - + - @@ -40,6 +40,17 @@ + + + + + diff --git a/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml.cs b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml.cs index c002243c5..c15bdda77 100644 --- a/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml.cs +++ b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml.cs @@ -21,8 +21,8 @@ namespace Wox.Plugin.Caculator.Views /// public partial class CalculatorSettings : UserControl { - private SettingsViewModel _viewModel; - private Settings _settings; + private readonly SettingsViewModel _viewModel; + private readonly Settings _settings; public CalculatorSettings(SettingsViewModel viewModel) { @@ -35,6 +35,7 @@ namespace Wox.Plugin.Caculator.Views private void CalculatorSettings_Loaded(object sender, RoutedEventArgs e) { DecimalSeparatorComboBox.SelectedItem = _settings.DecimalSeparator; + MaxDecimalPlaces.SelectedItem = _settings.MaxDecimalPlaces; } } From 0933eab4b0c1243c3d63fc714ff48f2bbb524d44 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Wed, 26 Feb 2020 20:46:47 +0100 Subject: [PATCH 16/20] Update Mages version --- Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj b/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj index c682cd19a..f24ad118e 100644 --- a/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj +++ b/Plugins/Wox.Plugin.Calculator/Wox.Plugin.Calculator.csproj @@ -134,7 +134,7 @@ 10.3.0 - 1.5.0 + 1.6.0 4.0.0 From cc743aeeeaadfd8fa11a57b0b8070849d258d3a6 Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Wed, 26 Feb 2020 20:47:14 +0100 Subject: [PATCH 17/20] Round result using new introduced setting --- Plugins/Wox.Plugin.Calculator/Main.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Plugins/Wox.Plugin.Calculator/Main.cs b/Plugins/Wox.Plugin.Calculator/Main.cs index 5d7b347d1..f2f7f7e18 100644 --- a/Plugins/Wox.Plugin.Calculator/Main.cs +++ b/Plugins/Wox.Plugin.Calculator/Main.cs @@ -63,7 +63,9 @@ namespace Wox.Plugin.Caculator if (!string.IsNullOrEmpty(result?.ToString())) { - string newResult = ChangeDecimalSeparator(result, GetDecimalSeparator()); + decimal roundedResult = Math.Round(Convert.ToDecimal(result), _settings.MaxDecimalPlaces, MidpointRounding.AwayFromZero); + string newResult = ChangeDecimalSeparator(roundedResult, GetDecimalSeparator()); + return new List { new Result @@ -118,13 +120,8 @@ namespace Wox.Plugin.Caculator return true; } - private string ChangeDecimalSeparator(object value, string newDecimalSeparator) + private string ChangeDecimalSeparator(decimal value, string newDecimalSeparator) { - if (value == null || String.IsNullOrEmpty(value.ToString())) - { - return string.Empty; - } - if (String.IsNullOrEmpty(newDecimalSeparator)) { return value.ToString(); @@ -134,7 +131,7 @@ namespace Wox.Plugin.Caculator { NumberDecimalSeparator = newDecimalSeparator }; - return Convert.ToDecimal(value).ToString(numberFormatInfo); + return value.ToString(numberFormatInfo); } private string GetDecimalSeparator() From 9d447ca63fd0628d8aa95d1e9dcbb717d14c790e Mon Sep 17 00:00:00 2001 From: SysC0mp Date: Wed, 26 Feb 2020 20:49:39 +0100 Subject: [PATCH 18/20] Replace static text with localized label --- Plugins/Wox.Plugin.Calculator/Languages/de.xaml | 1 + Plugins/Wox.Plugin.Calculator/Languages/en.xaml | 1 + Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Plugins/Wox.Plugin.Calculator/Languages/de.xaml b/Plugins/Wox.Plugin.Calculator/Languages/de.xaml index f5f1b27b5..eb6847af0 100644 --- a/Plugins/Wox.Plugin.Calculator/Languages/de.xaml +++ b/Plugins/Wox.Plugin.Calculator/Languages/de.xaml @@ -12,4 +12,5 @@ Systemeinstellung nutzen Komma (,) Punkt (.) + Max. Nachkommastellen \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Calculator/Languages/en.xaml b/Plugins/Wox.Plugin.Calculator/Languages/en.xaml index e214919d1..0df0d3342 100644 --- a/Plugins/Wox.Plugin.Calculator/Languages/en.xaml +++ b/Plugins/Wox.Plugin.Calculator/Languages/en.xaml @@ -12,4 +12,5 @@ Use system locale Comma (,) Dot (.) + Max. decimal places \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml index 0cb21c550..183f10e5f 100644 --- a/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml +++ b/Plugins/Wox.Plugin.Calculator/Views/CalculatorSettings.xaml @@ -41,7 +41,7 @@ - + Date: Thu, 27 Feb 2020 09:14:45 +1100 Subject: [PATCH 19/20] Add empty actionParameters check (#148) --- Wox.Core/Plugin/QueryBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Wox.Core/Plugin/QueryBuilder.cs b/Wox.Core/Plugin/QueryBuilder.cs index b8ac41988..b01a93291 100644 --- a/Wox.Core/Plugin/QueryBuilder.cs +++ b/Wox.Core/Plugin/QueryBuilder.cs @@ -24,7 +24,7 @@ namespace Wox.Core.Plugin { // use non global plugin for query actionKeyword = possibleActionKeyword; actionParameters = terms.Skip(1).ToList(); - search = rawQuery.Substring(actionKeyword.Length + 1); + search = actionParameters.Count > 0 ? rawQuery.Substring(actionKeyword.Length + 1) : string.Empty; } else { // non action keyword From 3184f8d275decd7d8a068e193d797b3cf8d03d75 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Thu, 27 Feb 2020 09:16:09 +1100 Subject: [PATCH 20/20] Update readme with main features released from this fork (#149) * Update readme with main features released from this fork * update --- README.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2b9da637f..00069024a 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,22 @@ Features - Search for everything—applications, **uwp**, folders, files and more. - Use *pinyin* to search for programs / 支持用 **拼音** 搜索程序 - wyy / wangyiyun → 网易云音乐 -- Keyword plugin search - - search google with `g search_term` +- Keyword plugin search `g search_term` +- Search youtube, google, twitter and many more - Build custom themes at http://www.wox.one/theme/builder - Install plugins from http://www.wox.one/plugin +**New from this fork:** +- Portable mode +- Drastically improved search experience +- Search all subfolders and files +- Option to always run CMD or Powershell as administrator +- Run CMD, Powershell and programs as a different user +- Manage what programs should be loaded +- Highlighting of how results are matched during query search +- Open web search result as a tab or a new window +- Automatic update +- Reload/update plugin data Installation ------------ @@ -42,8 +53,8 @@ Versions marked as **pre-release** are unstable pre-release versions. - Requirements: - .net >= 4.5.2 - - [everything](https://www.voidtools.com/): `.exe` installer + use x64 if your windows is x64 + everything service is running - - [python3](https://www.python.org/downloads/): `.exe` installer + add it to `%PATH%` or set it in WoX settings + - If you want to integrate with [everything](https://www.voidtools.com/): `.exe` installer + use x64 if your windows is x64 + everything service is running. Supported version is 1.3.4.686 + - If you use python plugins, install [python3](https://www.python.org/downloads/): `.exe` installer + add it to `%PATH%` or set it in WoX settings Usage -----