mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-11-27 14:59:16 +08:00
parent
27e609f6eb
commit
fc9d7e4f1b
5
.github/actions/spell-check/expect.txt
vendored
5
.github/actions/spell-check/expect.txt
vendored
@ -49,6 +49,7 @@ AModifier
|
||||
AMPROPERTY
|
||||
AMPROPSETID
|
||||
anges
|
||||
angularsen
|
||||
ansicolor
|
||||
ANull
|
||||
AOC
|
||||
@ -1497,6 +1498,7 @@ ppv
|
||||
pragma
|
||||
prc
|
||||
precomp
|
||||
Prefixer
|
||||
Preinstalled
|
||||
preload
|
||||
PREMULTIPLIED
|
||||
@ -1745,6 +1747,7 @@ shldisp
|
||||
shlobj
|
||||
shlwapi
|
||||
shobjidl
|
||||
shortsplit
|
||||
SHORTCUTATLEAST
|
||||
shortcutcontrol
|
||||
Shortcutguide
|
||||
@ -2028,6 +2031,8 @@ uninstantiated
|
||||
Uniq
|
||||
uniquifier
|
||||
Uniquifies
|
||||
unitconvert
|
||||
unitconverter
|
||||
unittests
|
||||
unk
|
||||
unknwn
|
||||
|
@ -147,6 +147,7 @@ steps:
|
||||
configuration: '$(BuildConfiguration)'
|
||||
testSelector: 'testAssemblies'
|
||||
testAssemblyVer2: |
|
||||
**\Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.dll
|
||||
**\Microsoft.Plugin.Folder.UnitTests.dll
|
||||
**\Microsoft.Plugin.Program.UnitTests.dll
|
||||
**\Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.dll
|
||||
|
@ -123,10 +123,6 @@ build:
|
||||
- 'modules\launcher\Plugins\Calculator\Microsoft.PowerToys.Run.Plugin.Calculator.dll'
|
||||
- 'modules\launcher\Plugins\Calculator\ManagedTelemetry.dll'
|
||||
- 'modules\launcher\Plugins\UnitConverter\Community.PowerToys.Run.Plugin.UnitConverter.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator\Microsoft.PowerToys.Run.Plugin.Calculator.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator\Wox.Infrastructure.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator\Wox.Plugin.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator\Telemetry.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Folder\Microsoft.Plugin.Folder.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Folder\ManagedTelemetry.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Indexer\Microsoft.Plugin.Indexer.dll'
|
||||
|
@ -145,14 +145,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Launcher", "src\m
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerLauncher", "src\modules\launcher\PowerLauncher\PowerLauncher.csproj", "{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{FD8EB419-FF9C-4D88-BB6F-BF6CED37747B} = {FD8EB419-FF9C-4D88-BB6F-BF6CED37747B}
|
||||
{03276A39-D4E9-417C-8FFD-200B0EE5E871} = {03276A39-D4E9-417C-8FFD-200B0EE5E871}
|
||||
{4D971245-7A70-41D5-BAA0-DDB5684CAF51} = {4D971245-7A70-41D5-BAA0-DDB5684CAF51}
|
||||
{FDB3555B-58EF-4AE6-B5F1-904719637AB4} = {FDB3555B-58EF-4AE6-B5F1-904719637AB4}
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4} = {BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}
|
||||
{59BD9891-3837-438A-958D-ADC7F91F6F7E} = {59BD9891-3837-438A-958D-ADC7F91F6F7E}
|
||||
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}
|
||||
{0351ADA4-0C32-4652-9BA0-41F7B602372B} = {0351ADA4-0C32-4652-9BA0-41F7B602372B}
|
||||
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {787B8AA6-CA93-4C84-96FE-DF31110AD1C4}
|
||||
{F8B870EB-D5F5-45BA-9CF7-A5C459818820} = {F8B870EB-D5F5-45BA-9CF7-A5C459818820}
|
||||
{74F1B9ED-F59C-4FE7-B473-7B453E30837E} = {74F1B9ED-F59C-4FE7-B473-7B453E30837E}
|
||||
{4BABF3FE-3451-42FD-873F-3C332E18DCEF} = {4BABF3FE-3451-42FD-873F-3C332E18DCEF}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{E775CC2C-24CB-48D6-9C3A-BE4CCE0DB17A}"
|
||||
@ -325,8 +329,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditorTest",
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "espresso", "espresso", "{127F38E0-40AA-4594-B955-5616BF206882}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Community.PowerToys.Run.Plugin.UnitConverter", "src\modules\launcher\Plugins\Community.PowerToys.Run.Plugin.UnitConverter\Community.PowerToys.Run.Plugin.UnitConverter.csproj", "{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EspressoModuleInterface", "src\modules\espresso\EspressoModuleInterface\EspressoModuleInterface.vcxproj", "{5E7360A8-D048-4ED3-8F09-0BFD64C5529A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Community.PowerToys.Run.Plugin.UnitConverter.UnitTest", "src\modules\launcher\Plugins\Community.PowerToys.Run.Plugin.UnitConverter.UnitTest\Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.csproj", "{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Espresso", "src\modules\espresso\Espresso\Espresso.csproj", "{D940E07F-532C-4FF3-883F-790DA014F19A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shortcutguide", "shortcutguide", "{106CBECA-0701-4FC3-838C-9DF816A19AE2}"
|
||||
@ -675,6 +683,14 @@ Global
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Debug|x64.Build.0 = Debug|x64
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Release|x64.ActiveCfg = Release|x64
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Release|x64.Build.0 = Release|x64
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}.Debug|x64.Build.0 = Debug|x64
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}.Release|x64.ActiveCfg = Release|x64
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}.Release|x64.Build.0 = Release|x64
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}.Debug|x64.Build.0 = Debug|x64
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}.Release|x64.ActiveCfg = Release|x64
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}.Release|x64.Build.0 = Release|x64
|
||||
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81}.Debug|x64.Build.0 = Debug|x64
|
||||
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81}.Release|x64.ActiveCfg = Release|x64
|
||||
@ -783,6 +799,8 @@ Global
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{127F38E0-40AA-4594-B955-5616BF206882} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A} = {127F38E0-40AA-4594-B955-5616BF206882}
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A} = {127F38E0-40AA-4594-B955-5616BF206882}
|
||||
{106CBECA-0701-4FC3-838C-9DF816A19AE2} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81} = {106CBECA-0701-4FC3-838C-9DF816A19AE2}
|
||||
|
@ -0,0 +1,31 @@
|
||||
# Unit Converter Plugin
|
||||
The Unit Convert plugin as the name suggests is used to perform unit conversion on the user entered query.
|
||||
This plugin uses a package called [UnitsNet](https://github.com/angularsen/UnitsNet).
|
||||
|
||||
![Image of Calculator plugin](/doc/images/launcher/plugins/community.unitconverter.png)
|
||||
|
||||
### Currently Supported Units
|
||||
- [Acceleration](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/AccelerationUnit.g.cs)
|
||||
- [Angle](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/AngleUnit.g.cs)
|
||||
- [Area](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/AreaUnit.g.cs)
|
||||
- [Duration](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/DurationUnit.g.cs)
|
||||
- [Energy](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/EnergyUnit.g.cs)
|
||||
- [Information](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/InformationUnit.g.cs)
|
||||
- [Length](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/LengthUnit.g.cs)
|
||||
- [Mass](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/MassUnit.g.cs)
|
||||
- [Power](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/PowerUnit.g.cs)
|
||||
- [Pressure](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/PressureUnit.g.cs)
|
||||
- [Speed](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/SpeedUnit.g.cs)
|
||||
- [Temperature](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/TemperatureUnit.g.cs)
|
||||
- [Volume](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/VolumeUnit.g.cs)
|
||||
|
||||
These are the ones that are currently enabled (though UnitsNet supports many more). They are defined in [`Main.cs`](/src/modules/launcher/Plugins/Community.PowerToys.Run.UnitConverter/Main.cs).
|
||||
|
||||
|
||||
### [`InputInterpreter`](/src/modules/launcher/Plugins/Community.PowerToys.Run.UnitConverter/InputInterpreter.cs)
|
||||
- Class which manipulates user input such that it may be interpreted correctly and thus converted.
|
||||
- Uses a regex amongst other things to do this.
|
||||
|
||||
### [`UnitHandler`](/src/modules/launcher/Plugins/Community.PowerToys.Run.UnitConverter/UnitHandler.cs)
|
||||
- Class that does the actual conversion.
|
||||
- Supports abbreviations in user input (single, double, or none).
|
BIN
doc/images/launcher/plugins/community.unitconverter.png
Normal file
BIN
doc/images/launcher/plugins/community.unitconverter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
@ -276,6 +276,10 @@
|
||||
<Directory Id="UriImagesFolder" Name="Images" />
|
||||
<Directory Id="UriLanguagesFolder" Name="Languages" />
|
||||
</Directory>
|
||||
<Directory Id="UnitConverterPluginFolder" Name="UnitConverter">
|
||||
<Directory Id="UnitConverterImagesFolder" Name="Images" />
|
||||
<Directory Id="UnitConverterLanguagesFolder" Name="Languages" />
|
||||
</Directory>
|
||||
<Directory Id="VSCodeWorkspacesPluginFolder" Name="VSCodeWorkspace">
|
||||
<Directory Id="VSCodeWorkspaceImagesFolder" Name="Images" />
|
||||
<Directory Id="VSCodeWorkspaceLanguagesFolder" Name="Languages" />
|
||||
@ -907,7 +911,7 @@
|
||||
<Fragment>
|
||||
<!-- Resource directories should be added only if the installer is built on the build farm -->
|
||||
<?ifdef env.IsPipeline?>
|
||||
<?foreach ParentDirectory in LauncherInstallFolder;FancyZonesInstallFolder;ImageResizerInstallFolder;ColorPickerInstallFolder;FileExplorerPreviewInstallFolder;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;RegistryPluginFolder;VSCodeWorkspacesPluginFolder;ServicePluginFolder;SystemPluginFolder?>
|
||||
<?foreach ParentDirectory in LauncherInstallFolder;FancyZonesInstallFolder;ImageResizerInstallFolder;ColorPickerInstallFolder;FileExplorerPreviewInstallFolder;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UnitConverterPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;RegistryPluginFolder;VSCodeWorkspacesPluginFolder;ServicePluginFolder;SystemPluginFolder?>
|
||||
<DirectoryRef Id="$(var.ParentDirectory)">
|
||||
<!-- Resource file directories -->
|
||||
<?foreach Language in $(var.LocLanguageList)?>
|
||||
@ -1015,7 +1019,7 @@
|
||||
|
||||
<Component Id="launcherInstallComponent" Directory="LauncherInstallFolder" Guid="5E688DB4-C522-4268-BA54-ED1CDFFE9DB6">
|
||||
<File Source="$(var.BinX64Dir)modules\Launcher\Microsoft.Launcher.dll" />
|
||||
<?foreach File in concrt140_app.dll;ICSharpCode.SharpZipLib.dll;JetBrains.Annotations.dll;Mages.Core.dll;Microsoft.Search.Interop.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerLauncher.deps.json;PowerLauncher.dll;PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;System.Text.Json.dll;PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToysInterop.dll;ManagedTelemetry.dll;PowerLauncher.Telemetry.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.Configuration.Binder.dll;Microsoft.Extensions.Configuration.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;ManagedCommon.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll?>
|
||||
<?foreach File in concrt140_app.dll;ICSharpCode.SharpZipLib.dll;JetBrains.Annotations.dll;Mages.Core.dll;Microsoft.Search.Interop.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerLauncher.deps.json;PowerLauncher.dll;PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;System.Text.Json.dll;PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;UnitsNet.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToysInterop.dll;ManagedTelemetry.dll;PowerLauncher.Telemetry.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.Configuration.Binder.dll;Microsoft.Extensions.Configuration.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;ManagedCommon.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll?>
|
||||
<File Id="File_$(var.File)" Source="$(var.BinX64Dir)modules\launcher\$(var.File)" />
|
||||
<?endforeach?>
|
||||
<File Source="$(var.BinX64Dir)Settings\Microsoft.PowerToys.Settings.UI.Lib.dll" />
|
||||
@ -1090,6 +1094,17 @@
|
||||
<?endforeach?>
|
||||
</Component>
|
||||
|
||||
<!-- UnitConverter Plugin -->
|
||||
<Component Id="UnitConverterComponent" Directory="UnitConverterPluginFolder" Guid="D4F429E3-C619-49D6-9416-88A757D18E02">
|
||||
<?foreach File in plugin.json;Community.PowerToys.Run.Plugin.UnitConverter.deps.json;Community.PowerToys.Run.Plugin.UnitConverter.dll?>
|
||||
<File Id="UnitConverter_$(var.File)" Source="$(var.BinX64Dir)modules\launcher\Plugins\Community.UnitConverter\$(var.File)" />
|
||||
<?endforeach?>
|
||||
</Component>
|
||||
<Component Id="UnitConverterImagesComponent" Directory="UnitConverterImagesFolder" Guid="16ABD217-0898-47B2-89D9-AF1ABF00F543">
|
||||
<File Id="UnitConverterLight" Source="$(var.BinX64Dir)modules\launcher\Plugins\Community.UnitConverter\Images\unitconverter.light.png" />
|
||||
<File Id="UnitConverterDark" Source="$(var.BinX64Dir)modules\launcher\Plugins\Community.UnitConverter\Images\unitconverter.dark.png" />
|
||||
</Component>
|
||||
|
||||
<!-- Uri Plugin -->
|
||||
<Component Id="UriComponent" Directory="UriPluginFolder" Guid="C7DC8F88-554C-4375-9510-9435399B5D3D">
|
||||
<?foreach File in plugin.json;Microsoft.Plugin.Uri.deps.json;Microsoft.Plugin.Uri.dll;ManagedTelemetry.dll?>
|
||||
|
@ -0,0 +1,37 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\..\..\codeAnalysis\StyleCop.json" Link="StyleCop.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\..\codeAnalysis\GlobalSuppressions.cs" Link="GlobalSuppressions.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Community.PowerToys.Run.Plugin.UnitConverter\Community.PowerToys.Run.Plugin.UnitConverter.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,67 @@
|
||||
using System.Globalization;
|
||||
using NUnit.Framework;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.UnitConverter.UnitTest
|
||||
{
|
||||
[TestFixture]
|
||||
public class InputInterpreterTests
|
||||
{
|
||||
[TestCase(new string[] { "1,5'" }, new string[] { "1,5", "'" })]
|
||||
[TestCase(new string[] { "1.5'" }, new string[] { "1.5", "'" })]
|
||||
[TestCase(new string[] { "1'" }, new string[] { "1", "'" })]
|
||||
[TestCase(new string[] { "1'5\"" }, new string[] { "1", "'", "5", "\"" })]
|
||||
[TestCase(new string[] { "5\"" }, new string[] { "5", "\"" })]
|
||||
[TestCase(new string[] { "1'5" }, new string[] { "1", "'", "5" })]
|
||||
public void RegexSplitsInput(string[] input, string[] expectedResult)
|
||||
{
|
||||
string[] shortsplit = InputInterpreter.RegexSplitter(input);
|
||||
Assert.AreEqual(expectedResult, shortsplit);
|
||||
}
|
||||
|
||||
[TestCase(new string[] { "1cm", "to", "mm" }, new string[] { "1", "cm", "to", "mm" })]
|
||||
public void InsertsSpaces(string[] input, string[] expectedResult)
|
||||
{
|
||||
InputInterpreter.InputSpaceInserter(ref input);
|
||||
Assert.AreEqual(expectedResult, input);
|
||||
}
|
||||
|
||||
[TestCase(new string[] { "1'", "in", "cm" }, new string[] { "1", "foot", "in", "cm" })]
|
||||
[TestCase(new string[] { "1\"", "in", "cm" }, new string[] { "1", "inch", "in", "cm" })]
|
||||
[TestCase(new string[] { "1'6", "in", "cm" }, new string[] { "1.5", "foot", "in", "cm" })]
|
||||
[TestCase(new string[] { "1'6\"", "in", "cm" }, new string[] { "1.5", "foot", "in", "cm" })]
|
||||
public void HandlesShorthandFeetInchNotation(string[] input, string[] expectedResult)
|
||||
{
|
||||
InputInterpreter.ShorthandFeetInchHandler(ref input, CultureInfo.InvariantCulture);
|
||||
Assert.AreEqual(expectedResult, input);
|
||||
}
|
||||
|
||||
[TestCase(new string[] { "5", "CeLsIuS", "in", "faHrenheiT" }, new string[] { "5", "DegreeCelsius", "in", "DegreeFahrenheit" })]
|
||||
[TestCase(new string[] { "5", "f", "in", "celsius" }, new string[] { "5", "°f", "in", "DegreeCelsius" })]
|
||||
[TestCase(new string[] { "5", "c", "in", "f" }, new string[] { "5", "°c", "in", "°f" })]
|
||||
[TestCase(new string[] { "5", "f", "in", "c" }, new string[] { "5", "°f", "in", "°c" })]
|
||||
public void PrefixesDegrees(string[] input, string[] expectedResult)
|
||||
{
|
||||
InputInterpreter.DegreePrefixer(ref input);
|
||||
Assert.AreEqual(expectedResult, input);
|
||||
}
|
||||
|
||||
[TestCase("a f in c")]
|
||||
[TestCase("12 f in")]
|
||||
public void ParseInvalidQueries(string queryString)
|
||||
{
|
||||
Query query = new Query(queryString);
|
||||
var result = InputInterpreter.Parse(query);
|
||||
Assert.AreEqual(null, result);
|
||||
}
|
||||
|
||||
[TestCase("12 f in c", 12)]
|
||||
[TestCase("10m to cm", 10)]
|
||||
public void ParseValidQueries(string queryString, double result)
|
||||
{
|
||||
Query query = new Query(queryString);
|
||||
var convertModel = InputInterpreter.Parse(query);
|
||||
Assert.AreEqual(result, convertModel.Value);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.UnitConverter.UnitTest
|
||||
{
|
||||
[TestFixture]
|
||||
public class UnitHandlerTests
|
||||
{
|
||||
[Test]
|
||||
public void HandleTemperature()
|
||||
{
|
||||
var convertModel = new ConvertModel(1, "DegreeCelsius", "DegreeFahrenheit");
|
||||
double result = UnitHandler.ConvertInput(convertModel, UnitsNet.QuantityType.Temperature);
|
||||
Assert.AreEqual(33.79999999999999d, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HandleLength()
|
||||
{
|
||||
var convertModel = new ConvertModel(1, "meter", "centimeter");
|
||||
double result = UnitHandler.ConvertInput(convertModel, UnitsNet.QuantityType.Length);
|
||||
Assert.AreEqual(100, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HandlesByteCapitals()
|
||||
{
|
||||
var convertModel = new ConvertModel(1, "kB", "kb");
|
||||
double result = UnitHandler.ConvertInput(convertModel, UnitsNet.QuantityType.Information);
|
||||
Assert.AreEqual(8, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HandleInvalidModel()
|
||||
{
|
||||
var convertModel = new ConvertModel(1, "aa", "bb");
|
||||
var results = UnitHandler.Convert(convertModel);
|
||||
Assert.AreEqual(0, results.Count());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
<Import Project="..\..\..\..\Version.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<ProjectGuid>{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}</ProjectGuid>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Community.PowerToys.Run.Plugin.UnitConverter</RootNamespace>
|
||||
<AssemblyName>Community.PowerToys.Run.Plugin.UnitConverter</AssemblyName>
|
||||
<Version>$(Version).0</Version>
|
||||
<useWPF>true</useWPF>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<Platforms>x64</Platforms>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Community.UnitConverter\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutputPath>..\..\..\..\..\x64\Release\modules\launcher\Plugins\Community.UnitConverter\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\..\..\codeAnalysis\StyleCop.json" Link="StyleCop.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\..\codeAnalysis\GlobalSuppressions.cs" Link="GlobalSuppressions.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="plugin.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="UnitsNet" Version="4.76.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Images\unitconverter.light.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\unitconverter.dark.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,26 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.UnitConverter
|
||||
{
|
||||
public class ConvertModel
|
||||
{
|
||||
public double Value { get; set; }
|
||||
|
||||
public string FromUnit { get; set; }
|
||||
|
||||
public string ToUnit { get; set; }
|
||||
|
||||
public ConvertModel()
|
||||
{
|
||||
}
|
||||
|
||||
public ConvertModel(double value, string fromUnit, string toUnit)
|
||||
{
|
||||
Value = value;
|
||||
FromUnit = fromUnit;
|
||||
ToUnit = toUnit;
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnitsNet;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.UnitConverter
|
||||
{
|
||||
public static class InputInterpreter
|
||||
{
|
||||
private static string pattern = @"(?<=\d)(?![,.])(?=\D)|(?<=\D)(?<![,.])(?=\d)";
|
||||
|
||||
public static string[] RegexSplitter(string[] split)
|
||||
{
|
||||
return Regex.Split(split[0], pattern);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Separates input like: "1ft in cm" to "1 ft in cm"
|
||||
/// </summary>
|
||||
public static void InputSpaceInserter(ref string[] split)
|
||||
{
|
||||
if (split.Length != 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string[] parseInputWithoutSpace = Regex.Split(split[0], pattern);
|
||||
|
||||
if (parseInputWithoutSpace.Length > 1)
|
||||
{
|
||||
string[] firstEntryRemoved = split.Skip(1).ToArray();
|
||||
string[] newSplit = new string[] { parseInputWithoutSpace[0], parseInputWithoutSpace[1] };
|
||||
|
||||
split = newSplit.Concat(firstEntryRemoved).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces a split input array with shorthand feet/inch notation (1', 1'2" etc) to 'x foot in cm'.
|
||||
/// </summary>
|
||||
public static void ShorthandFeetInchHandler(ref string[] split, CultureInfo culture)
|
||||
{
|
||||
if (!split[0].Contains('\'') && !split[0].Contains('\"'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// catches 1' || 1" || 1'2 || 1'2" in cm
|
||||
// by converting it to "x foot in cm"
|
||||
if (split.Length == 3)
|
||||
{
|
||||
string[] shortsplit = RegexSplitter(split);
|
||||
|
||||
switch (shortsplit.Length)
|
||||
{
|
||||
case 2:
|
||||
// ex: 1' & 1"
|
||||
if (shortsplit[1] == "\'")
|
||||
{
|
||||
string[] newInput = new string[] { shortsplit[0], "foot", split[1], split[2] };
|
||||
split = newInput;
|
||||
}
|
||||
else if (shortsplit[1] == "\"")
|
||||
{
|
||||
string[] newInput = new string[] { shortsplit[0], "inch", split[1], split[2] };
|
||||
split = newInput;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
// ex: 1'2 and 1'2"
|
||||
if (shortsplit[1] == "\'")
|
||||
{
|
||||
bool isFeet = double.TryParse(shortsplit[0], NumberStyles.AllowDecimalPoint, culture, out double feet);
|
||||
bool isInches = double.TryParse(shortsplit[2], NumberStyles.AllowDecimalPoint, culture, out double inches);
|
||||
|
||||
if (!isFeet || !isInches)
|
||||
{
|
||||
// atleast one could not be parsed correctly
|
||||
break;
|
||||
}
|
||||
|
||||
string convertedTotalInFeet = Length.FromFeetInches(feet, inches).Feet.ToString(culture);
|
||||
|
||||
string[] newInput = new string[] { convertedTotalInFeet, "foot", split[1], split[2] };
|
||||
split = newInput;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds degree prefixes to degree units for shorthand notation. E.g. '10 c in fahrenheit' becomes '10 °c in DegreeFahrenheit'.
|
||||
/// </summary>
|
||||
public static void DegreePrefixer(ref string[] split)
|
||||
{
|
||||
switch (split[1].ToLower())
|
||||
{
|
||||
case "celsius":
|
||||
split[1] = "DegreeCelsius";
|
||||
break;
|
||||
|
||||
case "fahrenheit":
|
||||
split[1] = "DegreeFahrenheit";
|
||||
break;
|
||||
|
||||
case "c":
|
||||
split[1] = "°c";
|
||||
break;
|
||||
|
||||
case "f":
|
||||
split[1] = "°f";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (split[3].ToLower())
|
||||
{
|
||||
case "celsius":
|
||||
split[3] = "DegreeCelsius";
|
||||
break;
|
||||
|
||||
case "fahrenheit":
|
||||
split[3] = "DegreeFahrenheit";
|
||||
break;
|
||||
|
||||
case "c":
|
||||
split[3] = "°c";
|
||||
break;
|
||||
|
||||
case "f":
|
||||
split[3] = "°f";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static ConvertModel Parse(Query query)
|
||||
{
|
||||
string[] split = query.Search.Split(' ');
|
||||
|
||||
InputInterpreter.ShorthandFeetInchHandler(ref split, CultureInfo.CurrentCulture);
|
||||
InputInterpreter.InputSpaceInserter(ref split);
|
||||
|
||||
if (split.Length != 4)
|
||||
{
|
||||
// deny any other queries than:
|
||||
// 10 ft in cm
|
||||
// 10 ft to cm
|
||||
return null;
|
||||
}
|
||||
|
||||
InputInterpreter.DegreePrefixer(ref split);
|
||||
if (!double.TryParse(split[0], out double value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ConvertModel()
|
||||
{
|
||||
Value = value,
|
||||
FromUnit = split[1],
|
||||
ToUnit = split[3],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using ManagedCommon;
|
||||
using UnitsNet;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.UnitConverter
|
||||
{
|
||||
public class Main : IPlugin, IPluginI18n, IContextMenu, IDisposable
|
||||
{
|
||||
public string Name => Properties.Resources.plugin_name;
|
||||
|
||||
public string Description => Properties.Resources.plugin_description;
|
||||
|
||||
private PluginInitContext _context;
|
||||
private static string _icon_path;
|
||||
private bool _disposed;
|
||||
|
||||
public void Init(PluginInitContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(paramName: nameof(context));
|
||||
}
|
||||
|
||||
_context = context;
|
||||
_context.API.ThemeChanged += OnThemeChanged;
|
||||
UpdateIconPath(_context.API.GetCurrentTheme());
|
||||
}
|
||||
|
||||
public List<Result> Query(Query query)
|
||||
{
|
||||
if (query == null)
|
||||
{
|
||||
throw new ArgumentNullException(paramName: nameof(query));
|
||||
}
|
||||
|
||||
// Parse
|
||||
ConvertModel convertModel = InputInterpreter.Parse(query);
|
||||
if (convertModel == null)
|
||||
{
|
||||
return new List<Result>();
|
||||
}
|
||||
|
||||
// Convert
|
||||
return UnitHandler.Convert(convertModel)
|
||||
.Select(x => GetResult(x))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private Result GetResult(UnitConversionResult result)
|
||||
{
|
||||
return new Result
|
||||
{
|
||||
ContextData = result,
|
||||
Title = string.Format("{0} {1}", result.ConvertedValue, result.UnitName),
|
||||
IcoPath = _icon_path,
|
||||
Score = 300,
|
||||
SubTitle = string.Format(Properties.Resources.copy_to_clipboard, result.QuantityType),
|
||||
Action = c =>
|
||||
{
|
||||
var ret = false;
|
||||
var thread = new Thread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(result.ConvertedValue.ToString());
|
||||
ret = true;
|
||||
}
|
||||
catch (ExternalException)
|
||||
{
|
||||
MessageBox.Show(Properties.Resources.copy_failed);
|
||||
}
|
||||
});
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
thread.Start();
|
||||
thread.Join();
|
||||
return ret;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private ContextMenuResult CreateContextMenuEntry(UnitConversionResult result)
|
||||
{
|
||||
return new ContextMenuResult
|
||||
{
|
||||
PluginName = Name,
|
||||
Title = Properties.Resources.context_menu_copy,
|
||||
Glyph = "\xE8C8",
|
||||
FontFamily = "Segoe MDL2 Assets",
|
||||
AcceleratorKey = Key.Enter,
|
||||
Action = _ =>
|
||||
{
|
||||
bool ret = false;
|
||||
var thread = new Thread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(result.ConvertedValue.ToString());
|
||||
ret = true;
|
||||
}
|
||||
catch (ExternalException)
|
||||
{
|
||||
MessageBox.Show(Properties.Resources.copy_failed);
|
||||
}
|
||||
});
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
thread.Start();
|
||||
thread.Join();
|
||||
return ret;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
|
||||
{
|
||||
if (!(selectedResult?.ContextData is UnitConversionResult))
|
||||
{
|
||||
return new List<ContextMenuResult>();
|
||||
}
|
||||
|
||||
List<ContextMenuResult> contextResults = new List<ContextMenuResult>();
|
||||
UnitConversionResult result = selectedResult.ContextData as UnitConversionResult;
|
||||
contextResults.Add(CreateContextMenuEntry(result));
|
||||
|
||||
return contextResults;
|
||||
}
|
||||
|
||||
public string GetTranslatedPluginTitle()
|
||||
{
|
||||
return Properties.Resources.plugin_name;
|
||||
}
|
||||
|
||||
public string GetTranslatedPluginDescription()
|
||||
{
|
||||
return Properties.Resources.plugin_description;
|
||||
}
|
||||
|
||||
private void OnThemeChanged(Theme _, Theme newTheme)
|
||||
{
|
||||
UpdateIconPath(newTheme);
|
||||
}
|
||||
|
||||
private static void UpdateIconPath(Theme theme)
|
||||
{
|
||||
if (theme == Theme.Light || theme == Theme.HighContrastWhite)
|
||||
{
|
||||
_icon_path = "Images/unitconverter.light.png";
|
||||
}
|
||||
else
|
||||
{
|
||||
_icon_path = "Images/unitconverter.dark.png";
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_context.API.ThemeChanged -= OnThemeChanged;
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.UnitConverter.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Community.PowerToys.Run.Plugin.UnitConverter.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Copy (Enter).
|
||||
/// </summary>
|
||||
public static string context_menu_copy {
|
||||
get {
|
||||
return ResourceManager.GetString("context_menu_copy", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Copy failed.
|
||||
/// </summary>
|
||||
public static string copy_failed {
|
||||
get {
|
||||
return ResourceManager.GetString("copy_failed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Copy {0} to clipboard.
|
||||
/// </summary>
|
||||
public static string copy_to_clipboard {
|
||||
get {
|
||||
return ResourceManager.GetString("copy_to_clipboard", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Provides unit conversion (e.g. 10 ft in m)..
|
||||
/// </summary>
|
||||
public static string plugin_description {
|
||||
get {
|
||||
return ResourceManager.GetString("plugin_description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unit Converter.
|
||||
/// </summary>
|
||||
public static string plugin_name {
|
||||
get {
|
||||
return ResourceManager.GetString("plugin_name", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="context_menu_copy" xml:space="preserve">
|
||||
<value>Copy (Enter)</value>
|
||||
</data>
|
||||
<data name="copy_failed" xml:space="preserve">
|
||||
<value>Copy failed</value>
|
||||
</data>
|
||||
<data name="copy_to_clipboard" xml:space="preserve">
|
||||
<value>Copy {0} to clipboard</value>
|
||||
</data>
|
||||
<data name="plugin_description" xml:space="preserve">
|
||||
<value>Provides unit conversion (e.g. 10 ft in m).</value>
|
||||
</data>
|
||||
<data name="plugin_name" xml:space="preserve">
|
||||
<value>Unit Converter</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,20 @@
|
||||
using UnitsNet;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.UnitConverter
|
||||
{
|
||||
public class UnitConversionResult
|
||||
{
|
||||
public double ConvertedValue { get; }
|
||||
|
||||
public string UnitName { get; }
|
||||
|
||||
public QuantityType QuantityType { get; }
|
||||
|
||||
public UnitConversionResult(double convertedValue, string unitName, QuantityType quantityType)
|
||||
{
|
||||
ConvertedValue = convertedValue;
|
||||
UnitName = unitName;
|
||||
QuantityType = quantityType;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using UnitsNet;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.UnitConverter
|
||||
{
|
||||
public static class UnitHandler
|
||||
{
|
||||
private static readonly int _roundingFractionalDigits = 4;
|
||||
|
||||
private static readonly QuantityType[] _included = new QuantityType[]
|
||||
{
|
||||
QuantityType.Acceleration,
|
||||
QuantityType.Angle,
|
||||
QuantityType.Area,
|
||||
QuantityType.Duration,
|
||||
QuantityType.Energy,
|
||||
QuantityType.Information,
|
||||
QuantityType.Length,
|
||||
QuantityType.Mass,
|
||||
QuantityType.Power,
|
||||
QuantityType.Pressure,
|
||||
QuantityType.Speed,
|
||||
QuantityType.Temperature,
|
||||
QuantityType.Volume,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Given string representation of unit, converts it to the enum.
|
||||
/// </summary>
|
||||
/// <returns>Corresponding enum or null.</returns>
|
||||
private static Enum GetUnitEnum(string unit, QuantityInfo unitInfo)
|
||||
{
|
||||
UnitInfo first = Array.Find(unitInfo.UnitInfos, info => info.Name.ToLower() == unit.ToLower());
|
||||
if (first != null)
|
||||
{
|
||||
return first.Value;
|
||||
}
|
||||
|
||||
if (UnitParser.Default.TryParse(unit, unitInfo.UnitType, out Enum enum_unit))
|
||||
{
|
||||
return enum_unit;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given parsed ConvertModel, computes result. (E.g "1 foot in cm").
|
||||
/// </summary>
|
||||
/// <returns>The converted value as a double.</returns>
|
||||
public static double ConvertInput(ConvertModel convertModel, QuantityType quantityType)
|
||||
{
|
||||
QuantityInfo unitInfo = Quantity.GetInfo(quantityType);
|
||||
|
||||
var fromUnit = GetUnitEnum(convertModel.FromUnit, unitInfo);
|
||||
var toUnit = GetUnitEnum(convertModel.ToUnit, unitInfo);
|
||||
|
||||
if (fromUnit != null && toUnit != null)
|
||||
{
|
||||
return UnitsNet.UnitConverter.Convert(convertModel.Value, fromUnit, toUnit);
|
||||
}
|
||||
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given ConvertModel returns collection of possible results.
|
||||
/// </summary>
|
||||
/// <returns>The converted value as a double.</returns>
|
||||
public static IEnumerable<UnitConversionResult> Convert(ConvertModel convertModel)
|
||||
{
|
||||
var results = new List<UnitConversionResult>();
|
||||
foreach (QuantityType quantityType in _included)
|
||||
{
|
||||
double convertedValue = UnitHandler.ConvertInput(convertModel, quantityType);
|
||||
|
||||
if (!double.IsNaN(convertedValue))
|
||||
{
|
||||
UnitConversionResult result = new UnitConversionResult(Math.Round(convertedValue, _roundingFractionalDigits), convertModel.ToUnit, quantityType);
|
||||
results.Add(result);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"ID": "aa0ee9daff654fb7be452c2d77c471b9",
|
||||
"ActionKeyword": "%%",
|
||||
"IsGlobal": false,
|
||||
"Name": "Unit Converter",
|
||||
"Author": "ThiefZero",
|
||||
"Version": "0.0.1",
|
||||
"Language": "csharp",
|
||||
"Website": "https://github.com/ThiefZero",
|
||||
"IcoPathDark": "Images\\unitconverter.dark.png",
|
||||
"IcoPathLight": "Images\\unitconverter.light.png",
|
||||
"ExecuteFileName": "Community.PowerToys.Run.Plugin.UnitConverter.dll"
|
||||
}
|
@ -74,7 +74,6 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
|
||||
UpdateIconPath(Context.API.GetCurrentTheme());
|
||||
}
|
||||
|
||||
// Todo : Update with theme based IconPath
|
||||
private void UpdateIconPath(Theme theme)
|
||||
{
|
||||
if (theme == Theme.Light || theme == Theme.HighContrastWhite)
|
||||
|
@ -113,6 +113,7 @@
|
||||
<PackageReference Include="tlbimp-Microsoft.Search.Interop" Version="1.0.0">
|
||||
<NoWarn>NU1701</NoWarn>
|
||||
</PackageReference>
|
||||
<PackageReference Include="UnitsNet" Version="4.76.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
Loading…
Reference in New Issue
Block a user