From 2d4f58fc32acfad6758b9ee1591d6a31f66f0d7e Mon Sep 17 00:00:00 2001 From: Advaith A J Date: Sun, 22 Dec 2024 13:10:08 +0400 Subject: [PATCH] v1.5.0 --- .../CalculateEngine.cs | 77 +++++++++++++++++ .../Main.cs | 82 ++----------------- .../Settings.cs | 26 +++--- .../plugin.json | 2 +- README.md | 2 +- 5 files changed, 98 insertions(+), 91 deletions(-) create mode 100644 Community.PowerToys.Run.Plugin.CurrencyConverter/CalculateEngine.cs diff --git a/Community.PowerToys.Run.Plugin.CurrencyConverter/CalculateEngine.cs b/Community.PowerToys.Run.Plugin.CurrencyConverter/CalculateEngine.cs new file mode 100644 index 0000000..1367814 --- /dev/null +++ b/Community.PowerToys.Run.Plugin.CurrencyConverter/CalculateEngine.cs @@ -0,0 +1,77 @@ +using System.Globalization; +using System.Text; + +namespace Community.PowerToys.Run.Plugin.CurrencyConverter +{ + public static class CalculateEngine + { + private static bool HasPrecedence(char op1, char op2) + { + if (op2 == '(' || op2 == ')') + return false; + if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) + return false; + else + return true; + } + + private static double ApplyOp(char op, double b, double a) => op switch + { + '+' => a + b, + '-' => a - b, + '*' => a * b, + '/' when b != 0 => a / b, + '/' => throw new DivideByZeroException("Cannot divide by zero"), + _ => throw new ArgumentException("Invalid operator", nameof(op)) + }; + + public static double Evaluate(string expression, NumberFormatInfo formatter) + { + Stack values = new Stack(); + Stack ops = new Stack(); + + string separator = formatter.CurrencyDecimalSeparator; + for (int i = 0; i < expression.Length; i++) + { + if (expression[i] == ' ') + continue; + + if (expression[i] >= '0' && expression[i] <= '9') + { + StringBuilder sbuf = new StringBuilder(); + while (i < expression.Length && ((expression[i] >= '0' && expression[i] <= '9') || expression.Substring(i, separator.Length) == separator || char.IsWhiteSpace(expression[i]))) + { + if (!char.IsWhiteSpace(expression[i])) + sbuf.Append(expression[i]); + i += expression.Substring(i, separator.Length) == separator ? separator.Length : 1; + } + + values.Push(double.Parse(sbuf.ToString(), NumberStyles.Currency, formatter)); + i--; + } + + else if (expression[i] == '(') + ops.Push(expression[i]); + + else if (expression[i] == ')') + { + while (ops.Count > 0 && ops.Peek() != '(') + values.Push(ApplyOp(ops.Pop(), values.Pop(), values.Pop())); + ops.Pop(); + } + + else if (expression[i] == '+' || expression[i] == '-' || expression[i] == '*' || expression[i] == '/') + { + while (ops.Count > 0 && HasPrecedence(expression[i], ops.Peek())) + values.Push(ApplyOp(ops.Pop(), values.Pop(), values.Pop())); + ops.Push(expression[i]); + } + } + + while (ops.Count > 0) + values.Push(ApplyOp(ops.Pop(), values.Pop(), values.Pop())); + + return values.Pop(); + } + } +} diff --git a/Community.PowerToys.Run.Plugin.CurrencyConverter/Main.cs b/Community.PowerToys.Run.Plugin.CurrencyConverter/Main.cs index af3ed01..881c69e 100644 --- a/Community.PowerToys.Run.Plugin.CurrencyConverter/Main.cs +++ b/Community.PowerToys.Run.Plugin.CurrencyConverter/Main.cs @@ -5,7 +5,7 @@ using System.Globalization; using System.IO; using System.Net.Http; -using System.Text; +using System.Reflection; using System.Text.Json; using System.Text.RegularExpressions; using System.Windows.Input; @@ -201,26 +201,6 @@ private string GetCurrencyFromAlias(string currency) return (convertedAmount, precision); } - private bool HasPrecedence(char op1, char op2) - { - if (op2 == '(' || op2 == ')') - return false; - if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) - return false; - else - return true; - } - - private double ApplyOp(char op, double b, double a) => op switch - { - '+' => a + b, - '-' => a - b, - '*' => a * b, - '/' when b != 0 => a / b, - '/' => throw new DivideByZeroException("Cannot divide by zero"), - _ => throw new ArgumentException("Invalid operator", nameof(op)) - }; - private NumberFormatInfo GetNumberFormatInfo() { NumberFormatInfo nfi = new NumberFormatInfo(); @@ -243,57 +223,6 @@ private NumberFormatInfo GetNumberFormatInfo() return nfi; } - private double Evaluate(string expression) - { - Stack values = new Stack(); - Stack ops = new Stack(); - - NumberFormatInfo formatter = GetNumberFormatInfo(); - string separator = formatter.CurrencyDecimalSeparator; - - for (int i = 0; i < expression.Length; i++) - { - if (expression[i] == ' ') - continue; - - if (expression[i] >= '0' && expression[i] <= '9') - { - StringBuilder sbuf = new StringBuilder(); - while (i < expression.Length && ((expression[i] >= '0' && expression[i] <= '9') || expression.Substring(i, separator.Length) == separator || char.IsWhiteSpace(expression[i]))) - { - if (!char.IsWhiteSpace(expression[i])) - sbuf.Append(expression[i]); - i += expression.Substring(i, separator.Length) == separator ? separator.Length : 1; - } - - values.Push(double.Parse(sbuf.ToString(), NumberStyles.Currency, formatter)); - i--; - } - - else if (expression[i] == '(') - ops.Push(expression[i]); - - else if (expression[i] == ')') - { - while (ops.Count > 0 && ops.Peek() != '(') - values.Push(ApplyOp(ops.Pop(), values.Pop(), values.Pop())); - ops.Pop(); - } - - else if (expression[i] == '+' || expression[i] == '-' || expression[i] == '*' || expression[i] == '/') - { - while (ops.Count > 0 && HasPrecedence(expression[i], ops.Peek())) - values.Push(ApplyOp(ops.Pop(), values.Pop(), values.Pop())); - ops.Push(expression[i]); - } - } - - while (ops.Count > 0) - values.Push(ApplyOp(ops.Pop(), values.Pop(), values.Pop())); - - return values.Pop(); - } - private List GetConversionResults(bool isGlobal, double amountToConvert, string fromCurrency, string toCurrency) { List<(int index, string fromCurrency, Task task)> conversionTasks = []; @@ -389,7 +318,7 @@ private List ParseQuery(string search, bool isGlobal) { CultureInfo culture = CultureInfo.CurrentCulture; if (EnableLog) Log.Info("Converting the expression to number: " + match.Groups["amount"].Value.Replace(formatter.CurrencyGroupSeparator, ""), GetType()); - amountToConvert = Evaluate(match.Groups["amount"].Value.Replace(formatter.CurrencyGroupSeparator, "")); + amountToConvert = CalculateEngine.Evaluate(match.Groups["amount"].Value.Replace(formatter.CurrencyGroupSeparator, ""), GetNumberFormatInfo()); if (EnableLog) Log.Info("Converted number is: " + amountToConvert, GetType()); } catch (Exception) @@ -500,9 +429,10 @@ public void Init(PluginInitContext context) UpdateIconPath(_context.API.GetCurrentTheme()); _aliasFileLocation = Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "PowerToys", - "CurrencyConverter", + Constant.DataDirectory, + "Settings", + "Plugins", + Assembly.GetExecutingAssembly().GetName().Name, AliasFileName); EnsureAliasFileExists(); diff --git a/Community.PowerToys.Run.Plugin.CurrencyConverter/Settings.cs b/Community.PowerToys.Run.Plugin.CurrencyConverter/Settings.cs index 3002e9a..fa44d21 100644 --- a/Community.PowerToys.Run.Plugin.CurrencyConverter/Settings.cs +++ b/Community.PowerToys.Run.Plugin.CurrencyConverter/Settings.cs @@ -8,12 +8,12 @@ public class Settings { public PluginUpdateSettings Update { get; set; } = new PluginUpdateSettings { ResultScore = 100 }; - protected internal bool ShowWarningsInGlobal { get; set; } - protected internal int OutputStyle { get; set; } - protected internal int DecimalSeparator { get; set; } - protected internal int ConversionDirection { get; set; } - protected internal string LocalCurrency { get; set; } - protected internal string[] Currencies { get; set; } + public bool ShowWarningsInGlobal { get; set; } + public int OutputStyle { get; set; } + public int DecimalSeparator { get; set; } + public int ConversionDirection { get; set; } + public string LocalCurrency { get; set; } + public string[] Currencies { get; set; } protected internal IEnumerable GetAdditionalOptions() { @@ -26,7 +26,7 @@ protected internal IEnumerable GetAdditionalOptions() DisplayLabel = "Show warnings in global results", DisplayDescription = "Warnings from the plugin are suppressed when the \"Include in global result\" is checked", PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Checkbox, - Value = false, + Value = ShowWarningsInGlobal, }, new() { @@ -40,7 +40,7 @@ protected internal IEnumerable GetAdditionalOptions() new KeyValuePair("Always use dots for decimals", "1"), new KeyValuePair("Always use commas for decimals", "2"), ], - ComboBoxValue = 0, + ComboBoxValue = DecimalSeparator, }, new() { @@ -53,7 +53,7 @@ protected internal IEnumerable GetAdditionalOptions() new KeyValuePair("Short Text", "0"), new KeyValuePair("Full Text", "1"), ], - ComboBoxValue = 1, + ComboBoxValue = OutputStyle, }, new() { @@ -66,7 +66,7 @@ protected internal IEnumerable GetAdditionalOptions() new KeyValuePair("Local currency to other currencies", "0"), new KeyValuePair("Other currencies to local currency", "1"), ], - ComboBoxValue = 0, + ComboBoxValue = ConversionDirection, }, new() { @@ -74,7 +74,7 @@ protected internal IEnumerable GetAdditionalOptions() DisplayLabel = "Quick Conversion Local Currency", DisplayDescription = "Set your local currency for quick conversion", PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Textbox, - TextValue = (new RegionInfo(CultureInfo.CurrentCulture.Name)).ISOCurrencySymbol, + TextValue = LocalCurrency, }, new() { @@ -82,7 +82,7 @@ protected internal IEnumerable GetAdditionalOptions() DisplayLabel = "Quick Conversion Currencies", DisplayDescription = "Add currencies comma separated. eg: USD, EUR, BTC", PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Textbox, - TextValue = "USD", + TextValue = String.Join(", ", Currencies), } ]); @@ -106,7 +106,7 @@ protected internal void SetAdditionalOptions(IEnumerable .Split(',') .Select(x => x.Trim()) .Where(x => !string.IsNullOrEmpty(x)) - .ToArray(); + .ToArray(); Update.SetAdditionalOptions(additionalOptions); } diff --git a/Community.PowerToys.Run.Plugin.CurrencyConverter/plugin.json b/Community.PowerToys.Run.Plugin.CurrencyConverter/plugin.json index df8b78f..cac6776 100755 --- a/Community.PowerToys.Run.Plugin.CurrencyConverter/plugin.json +++ b/Community.PowerToys.Run.Plugin.CurrencyConverter/plugin.json @@ -4,7 +4,7 @@ "ActionKeyword": "$$", "Name": "CurrencyConverter", "Author": "advaith3600", - "Version": "1.4.1", + "Version": "1.5.0", "Language": "csharp", "Website": "https://github.com/advaith3600/PowerToys-Run-Currency-Converter", "ExecuteFileName": "Community.PowerToys.Run.Plugin.CurrencyConverter.dll", diff --git a/README.md b/README.md index 6e9e027..657bac1 100755 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ To make currency conversions more convenient, you can use aliasing to assign cus To set up aliasing, follow these steps: -1. Locate the configuration file `alias.json` in `Documents/PowerToys/CurrencyConverter`. +1. Locate the configuration file `alias.json` in `%LOCALAPPDATA%\Microsoft\PowerToys\PowerToys Run\Settings\Plugins\Community.PowerToys.Run.Plugin.CurrencyConverter`. 2. Open the `alias.json` file in a text editor. 3. Add an entry for each alias you want to create. Each entry should have the format `"alias": "currency_code"`. For example, to alias "dollar" to "usd", add the following entry: `"dollar": "usd"`. 4. Save the `alias.json` file.