Skip to content

Commit

Permalink
v1.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Advaith3600 committed Dec 22, 2024
1 parent 9241ade commit 2d4f58f
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 91 deletions.
Original file line number Diff line number Diff line change
@@ -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<double> values = new Stack<double>();
Stack<char> ops = new Stack<char>();

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();
}
}
}
82 changes: 6 additions & 76 deletions Community.PowerToys.Run.Plugin.CurrencyConverter/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -243,57 +223,6 @@ private NumberFormatInfo GetNumberFormatInfo()
return nfi;
}

private double Evaluate(string expression)
{
Stack<double> values = new Stack<double>();
Stack<char> ops = new Stack<char>();

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<Result> GetConversionResults(bool isGlobal, double amountToConvert, string fromCurrency, string toCurrency)
{
List<(int index, string fromCurrency, Task<Result?> task)> conversionTasks = [];
Expand Down Expand Up @@ -389,7 +318,7 @@ private List<Result> 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)
Expand Down Expand Up @@ -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();

Expand Down
26 changes: 13 additions & 13 deletions Community.PowerToys.Run.Plugin.CurrencyConverter/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<PluginAdditionalOption> GetAdditionalOptions()
{
Expand All @@ -26,7 +26,7 @@ protected internal IEnumerable<PluginAdditionalOption> 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()
{
Expand All @@ -40,7 +40,7 @@ protected internal IEnumerable<PluginAdditionalOption> GetAdditionalOptions()
new KeyValuePair<string, string>("Always use dots for decimals", "1"),
new KeyValuePair<string, string>("Always use commas for decimals", "2"),
],
ComboBoxValue = 0,
ComboBoxValue = DecimalSeparator,
},
new()
{
Expand All @@ -53,7 +53,7 @@ protected internal IEnumerable<PluginAdditionalOption> GetAdditionalOptions()
new KeyValuePair<string, string>("Short Text", "0"),
new KeyValuePair<string, string>("Full Text", "1"),
],
ComboBoxValue = 1,
ComboBoxValue = OutputStyle,
},
new()
{
Expand All @@ -66,23 +66,23 @@ protected internal IEnumerable<PluginAdditionalOption> GetAdditionalOptions()
new KeyValuePair<string, string>("Local currency to other currencies", "0"),
new KeyValuePair<string, string>("Other currencies to local currency", "1"),
],
ComboBoxValue = 0,
ComboBoxValue = ConversionDirection,
},
new()
{
Key = nameof(LocalCurrency),
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()
{
Key = nameof(Currencies),
DisplayLabel = "Quick Conversion Currencies",
DisplayDescription = "Add currencies comma separated. eg: USD, EUR, BTC",
PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Textbox,
TextValue = "USD",
TextValue = String.Join(", ", Currencies),
}
]);

Expand All @@ -106,7 +106,7 @@ protected internal void SetAdditionalOptions(IEnumerable<PluginAdditionalOption>
.Split(',')
.Select(x => x.Trim())
.Where(x => !string.IsNullOrEmpty(x))
.ToArray();
.ToArray();

Update.SetAdditionalOptions(additionalOptions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 2d4f58f

Please sign in to comment.