From 9a386d25f4e8a7ce10a9d44115e8dc9b675a9544 Mon Sep 17 00:00:00 2001 From: chylex <contact@chylex.com> Date: Mon, 29 Jul 2024 16:57:33 +0200 Subject: [PATCH] Add project files before Git --- .gitignore | 3 + AppCalc/App.cs | 235 ++++++++++++++++++ AppCalc/AppCalc.csproj | 57 +++++ AppCalc/Operators.cs | 28 +++ AppCalc/Properties/AssemblyInfo.cs | 35 +++ AppConv/App.cs | 49 ++++ AppConv/AppConv.csproj | 69 +++++ AppConv/General/DecimalUnitConverterBase.cs | 126 ++++++++++ AppConv/General/DecimalUnitConverterSimple.cs | 66 +++++ AppConv/General/IUnitType.cs | 5 + AppConv/Properties/AssemblyInfo.cs | 35 +++ AppConv/Units/Angle.cs | 29 +++ AppConv/Units/Area.cs | 43 ++++ AppConv/Units/Length.cs | 84 +++++++ AppConv/Units/Radix.cs | 124 +++++++++ AppConv/Units/Storage.cs | 29 +++ AppConv/Units/Temperature.cs | 102 ++++++++ AppConv/Units/Volume.cs | 28 +++ AppConv/Units/Weight.cs | 25 ++ AppConv/Utils/RadixConversion.cs | 78 ++++++ AppConv/Utils/SI.cs | 89 +++++++ AppMeme/App.cs | 25 ++ AppMeme/AppMeme.csproj | 56 +++++ AppMeme/Properties/AssemblyInfo.cs | 35 +++ AppWindows/App.cs | 26 ++ AppWindows/AppSys.csproj | 59 +++++ AppWindows/Handlers/HandlerApps.cs | 58 +++++ AppWindows/Handlers/HandlerProcesses.cs | 49 ++++ AppWindows/IHandler.cs | 8 + AppWindows/Properties/AssemblyInfo.cs | 35 +++ Base/Base.csproj | 55 ++++ Base/Command.cs | 44 ++++ Base/CommandEventArgs.cs | 11 + Base/CommandException.cs | 8 + Base/IApp.cs | 8 + Base/MatchConfidence.cs | 8 + Base/Properties/AssemblyInfo.cs | 35 +++ Base/Utils/RegexUtils.cs | 23 ++ Query.sln | 60 +++++ Query/Controls/QueryHistoryLog.Designer.cs | 57 +++++ Query/Controls/QueryHistoryLog.cs | 43 ++++ Query/Controls/QueryTextBox.Designer.cs | 61 +++++ Query/Controls/QueryTextBox.cs | 158 ++++++++++++ Query/Core/CommandHistory.cs | 33 +++ Query/Core/CommandProcessor.cs | 65 +++++ Query/Core/KeyboardHook.cs | 64 +++++ Query/MainForm.Designer.cs | 135 ++++++++++ Query/MainForm.cs | 146 +++++++++++ Query/MainForm.resx | 219 ++++++++++++++++ Query/Program.cs | 13 + Query/Properties/AssemblyInfo.cs | 35 +++ Query/Properties/Resources.Designer.cs | 62 +++++ Query/Properties/Resources.resx | 117 +++++++++ Query/Properties/Settings.Designer.cs | 26 ++ Query/Properties/Settings.settings | 7 + Query/Query.csproj | 118 +++++++++ icon.ico | Bin 0 -> 2462 bytes 57 files changed, 3301 insertions(+) create mode 100644 AppCalc/App.cs create mode 100644 AppCalc/AppCalc.csproj create mode 100644 AppCalc/Operators.cs create mode 100644 AppCalc/Properties/AssemblyInfo.cs create mode 100644 AppConv/App.cs create mode 100644 AppConv/AppConv.csproj create mode 100644 AppConv/General/DecimalUnitConverterBase.cs create mode 100644 AppConv/General/DecimalUnitConverterSimple.cs create mode 100644 AppConv/General/IUnitType.cs create mode 100644 AppConv/Properties/AssemblyInfo.cs create mode 100644 AppConv/Units/Angle.cs create mode 100644 AppConv/Units/Area.cs create mode 100644 AppConv/Units/Length.cs create mode 100644 AppConv/Units/Radix.cs create mode 100644 AppConv/Units/Storage.cs create mode 100644 AppConv/Units/Temperature.cs create mode 100644 AppConv/Units/Volume.cs create mode 100644 AppConv/Units/Weight.cs create mode 100644 AppConv/Utils/RadixConversion.cs create mode 100644 AppConv/Utils/SI.cs create mode 100644 AppMeme/App.cs create mode 100644 AppMeme/AppMeme.csproj create mode 100644 AppMeme/Properties/AssemblyInfo.cs create mode 100644 AppWindows/App.cs create mode 100644 AppWindows/AppSys.csproj create mode 100644 AppWindows/Handlers/HandlerApps.cs create mode 100644 AppWindows/Handlers/HandlerProcesses.cs create mode 100644 AppWindows/IHandler.cs create mode 100644 AppWindows/Properties/AssemblyInfo.cs create mode 100644 Base/Base.csproj create mode 100644 Base/Command.cs create mode 100644 Base/CommandEventArgs.cs create mode 100644 Base/CommandException.cs create mode 100644 Base/IApp.cs create mode 100644 Base/MatchConfidence.cs create mode 100644 Base/Properties/AssemblyInfo.cs create mode 100644 Base/Utils/RegexUtils.cs create mode 100644 Query.sln create mode 100644 Query/Controls/QueryHistoryLog.Designer.cs create mode 100644 Query/Controls/QueryHistoryLog.cs create mode 100644 Query/Controls/QueryTextBox.Designer.cs create mode 100644 Query/Controls/QueryTextBox.cs create mode 100644 Query/Core/CommandHistory.cs create mode 100644 Query/Core/CommandProcessor.cs create mode 100644 Query/Core/KeyboardHook.cs create mode 100644 Query/MainForm.Designer.cs create mode 100644 Query/MainForm.cs create mode 100644 Query/MainForm.resx create mode 100644 Query/Program.cs create mode 100644 Query/Properties/AssemblyInfo.cs create mode 100644 Query/Properties/Resources.Designer.cs create mode 100644 Query/Properties/Resources.resx create mode 100644 Query/Properties/Settings.Designer.cs create mode 100644 Query/Properties/Settings.settings create mode 100644 Query/Query.csproj create mode 100644 icon.ico diff --git a/.gitignore b/.gitignore index 40da635..072d145 100644 --- a/.gitignore +++ b/.gitignore @@ -396,3 +396,6 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml + +# Custom +/.idea/ diff --git a/AppCalc/App.cs b/AppCalc/App.cs new file mode 100644 index 0000000..f51d0cc --- /dev/null +++ b/AppCalc/App.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using Base; + +namespace AppCalc{ + public sealed class App : IApp{ + private static readonly Regex RegexValidCharacters = new Regex(@"^[\s\d\.\-+*/%^]+$", RegexOptions.Compiled); + private static readonly Regex RegexTokenSeparator = new Regex(@"((?<!\d)-?(((\d+)?\.\d+(\.\.\.)?)|\d+))|[^\d\s]", RegexOptions.ExplicitCapture | RegexOptions.Compiled); + private static readonly Regex RegexRecurringDecimal = new Regex(@"\b(?:(\d+?\.\d{0,}?)(\d+?)\2+|([\d+?\.]*))\b", RegexOptions.Compiled); + + private static readonly char[] SplitSpace = { ' ' }; + + public string[] RecognizedNames => new string[]{ + "calc", + "calculate", + "calculator" + }; + + public MatchConfidence GetConfidence(Command cmd){ + return RegexValidCharacters.IsMatch(cmd.Text) ? MatchConfidence.Possible : MatchConfidence.None; + } + + string IApp.ProcessCommand(Command cmd){ + return ParseAndProcessExpression(cmd.Text); + } + + private static string ParseAndProcessExpression(string text){ + // text = RegexBalancedParentheses.Replace(text, match => " "+ParseAndProcessExpression(match.Groups[1].Value)+" "); // parens are handled as apps + + string expression = RegexTokenSeparator.Replace(text, match => " "+match.Value+" "); + string[] tokens = expression.Split(SplitSpace, StringSplitOptions.RemoveEmptyEntries); + + decimal result = ProcessExpression(tokens); + + if (Math.Abs(result-decimal.Round(result)) < 0.0000000000000000000000000010M){ + return decimal.Round(result).ToString(CultureInfo.InvariantCulture); + } + + string res = result.ToString(CultureInfo.InvariantCulture); + bool hasDecimalPoint = decimal.Round(result) != result; + + if (res.Length == 30 && hasDecimalPoint && res.IndexOf('.') < 15){ // Length 30 uses all available bytes + res = res.Substring(0, res.Length-1); + + Match match = RegexRecurringDecimal.Match(res); + + if (match.Groups[2].Success){ + string repeating = match.Groups[2].Value; + + StringBuilder build = new StringBuilder(34); + build.Append(match.Groups[1].Value); + + do{ + build.Append(repeating); + }while(build.Length+repeating.Length <= res.Length); + + return build.Append(repeating.Substring(0, 1+build.Length-res.Length)).Append("...").ToString(); + } + } + else if (hasDecimalPoint){ + res = res.TrimEnd('0'); + } + + return res; + } + + private static decimal ProcessExpression(string[] tokens){ + bool isPostfix; + + if (tokens.Length < 3){ + isPostfix = false; + } + else{ + try{ + ParseNumberToken(tokens[0]); + }catch(CommandException){ + throw new CommandException("Prefix notation is not supported."); + } + + try{ + ParseNumberToken(tokens[1]); + isPostfix = true; + }catch(CommandException){ + isPostfix = false; + } + } + + if (isPostfix){ + return ProcessPostfixExpression(tokens); + } + else{ + return ProcessPostfixExpression(ConvertInfixToPostfix(tokens)); + } + } + + private static IEnumerable<string> ConvertInfixToPostfix(IEnumerable<string> tokens){ + Stack<string> operators = new Stack<string>(); + + foreach(string token in tokens){ + if (Operators.With2Operands.Contains(token)){ + int currentPrecedence = Operators.GetPrecedence(token); + bool currentRightAssociative = Operators.IsRightAssociative(token); + + while(operators.Count > 0){ + int topPrecedence = Operators.GetPrecedence(operators.Peek()); + + if ((currentRightAssociative && currentPrecedence < topPrecedence) || (!currentRightAssociative && currentPrecedence <= topPrecedence)){ + yield return operators.Pop(); + } + else{ + break; + } + } + + operators.Push(token); + } + else{ + yield return ParseNumberToken(token).ToString(CultureInfo.InvariantCulture); + } + } + + while(operators.Count > 0){ + yield return operators.Pop(); + } + } + + private static decimal ProcessPostfixExpression(IEnumerable<string> tokens){ + Stack<decimal> stack = new Stack<decimal>(); + + foreach(string token in tokens){ + decimal operand1, operand2; + + if (token == "-" && stack.Count == 1){ + operand2 = stack.Pop(); + operand1 = 0M; + } + else if (Operators.With2Operands.Contains(token)){ + if (stack.Count < 2){ + throw new CommandException("Incorrect syntax, not enough numbers in stack."); + } + + operand2 = stack.Pop(); + operand1 = stack.Pop(); + } + else{ + operand1 = operand2 = 0M; + } + + switch(token){ + case "+": stack.Push(operand1+operand2); break; + case "-": stack.Push(operand1-operand2); break; + case "*": stack.Push(operand1*operand2); break; + + case "/": + if (operand2 == 0M){ + throw new CommandException("Cannot divide by zero."); + } + + stack.Push(operand1/operand2); + break; + + case "%": + if (operand2 == 0M){ + throw new CommandException("Cannot divide by zero."); + } + + stack.Push(operand1%operand2); + break; + + case "^": + if (operand1 == 0M && operand2 == 0M){ + throw new CommandException("Cannot evaluate 0 to the power of 0."); + } + else if (operand1 < 0M && Math.Abs(operand2) < 1M){ + throw new CommandException("Cannot evaluate a root of a negative number."); + } + + try{ + stack.Push((decimal)Math.Pow((double)operand1, (double)operand2)); + }catch(OverflowException ex){ + throw new CommandException("Number overflow.", ex); + } + + break; + + default: + stack.Push(ParseNumberToken(token)); + break; + } + } + + if (stack.Count != 1){ + throw new CommandException("Incorrect syntax, too many numbers in stack."); + } + + return stack.Pop(); + } + + private static decimal ParseNumberToken(string token){ + string str = token; + + if (str.StartsWith("-.")){ + str = "-0"+str.Substring(1); + } + else if (str[0] == '.'){ + str = "0"+str; + } + + if (str.EndsWith("...")){ + string truncated = str.Substring(0, str.Length-3); + + if (truncated.IndexOf('.') != -1){ + str = truncated; + } + } + + decimal value; + + if (decimal.TryParse(str, NumberStyles.Float, CultureInfo.InvariantCulture, out value)){ + if (value.ToString(CultureInfo.InvariantCulture) != str){ + throw new CommandException("Provided number is outside of decimal range: "+token); + } + + return value; + } + else{ + throw new CommandException("Invalid token, expected a number: "+token); + } + } + } +} diff --git a/AppCalc/AppCalc.csproj b/AppCalc/AppCalc.csproj new file mode 100644 index 0000000..2b5093a --- /dev/null +++ b/AppCalc/AppCalc.csproj @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{C7A21640-CAF3-40E8-AA6A-793181BD28AA}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>AppCalc</RootNamespace> + <AssemblyName>AppCalc</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>none</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + </ItemGroup> + <ItemGroup> + <Compile Include="App.cs" /> + <Compile Include="Operators.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Base\Base.csproj"> + <Project>{66CF4F71-50DD-4C65-AB96-35D1193FFB50}</Project> + <Name>Base</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file diff --git a/AppCalc/Operators.cs b/AppCalc/Operators.cs new file mode 100644 index 0000000..2bb7b38 --- /dev/null +++ b/AppCalc/Operators.cs @@ -0,0 +1,28 @@ +namespace AppCalc{ + internal static class Operators{ + internal static readonly string[] With2Operands = { "+", "-", "*", "/", "%", "^" }; + + internal static int GetPrecedence(string token){ + switch(token){ + case "^": + return 4; + + case "*": + case "/": + case "%": + return 3; + + case "+": + case "-": + return 2; + + default: + return 1; + } + } + + internal static bool IsRightAssociative(string token){ + return token == "^"; + } + } +} diff --git a/AppCalc/Properties/AssemblyInfo.cs b/AppCalc/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e4d69bc --- /dev/null +++ b/AppCalc/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AppCalc")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AppCalc")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8e0868ef-ce49-4d8b-b496-bf59f38e21bd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AppConv/App.cs b/AppConv/App.cs new file mode 100644 index 0000000..cbc6523 --- /dev/null +++ b/AppConv/App.cs @@ -0,0 +1,49 @@ +using System; +using System.Linq; +using AppConv.General; +using AppConv.Units; +using Base; + +namespace AppConv{ + public sealed class App : IApp{ + private static readonly IUnitType[] Processors = { + new Temperature(), + new Weight(), + new Length(), + new Area(), + new Volume(), + new Angle(), + new Storage(), + new Radix() + }; + + public string[] RecognizedNames => new string[]{ + "conv", + "convert" + }; + + public MatchConfidence GetConfidence(Command cmd){ + return cmd.Text.IndexOf(" to ", StringComparison.InvariantCultureIgnoreCase) != -1 ? MatchConfidence.Possible : MatchConfidence.None; + } + + public string ProcessCommand(Command cmd){ + string[] data = cmd.Text.Split(new string[]{ " to " }, 2, StringSplitOptions.None); + + string src = data[0].Trim(); + string dst = data[1].Trim(); + + if (src.Length == 0 || dst.Length == 0){ + throw new CommandException("Unrecognized conversion app syntax."); + } + + string result = string.Empty; + IUnitType used = Processors.FirstOrDefault(processor => processor.TryProcess(src, dst, out result)); + + if (used == null){ + throw new CommandException("Could not recognize conversion units."); + } + + return result; + } + } +} diff --git a/AppConv/AppConv.csproj b/AppConv/AppConv.csproj new file mode 100644 index 0000000..a5dea09 --- /dev/null +++ b/AppConv/AppConv.csproj @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{1AC5280A-81D1-4E02-9122-DB358734FFB4}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>AppConv</RootNamespace> + <AssemblyName>AppConv</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>none</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + </ItemGroup> + <ItemGroup> + <Compile Include="App.cs" /> + <Compile Include="General\DecimalUnitConverterBase.cs" /> + <Compile Include="General\DecimalUnitConverterSimple.cs" /> + <Compile Include="Units\Storage.cs" /> + <Compile Include="Units\Angle.cs" /> + <Compile Include="Units\Area.cs" /> + <Compile Include="Utils\RadixConversion.cs" /> + <Compile Include="Utils\SI.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Units\Radix.cs" /> + <Compile Include="Units\Volume.cs" /> + <Compile Include="Units\Length.cs" /> + <Compile Include="Units\Temperature.cs" /> + <Compile Include="General\IUnitType.cs" /> + <Compile Include="Units\Weight.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Base\Base.csproj"> + <Project>{66CF4F71-50DD-4C65-AB96-35D1193FFB50}</Project> + <Name>Base</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file diff --git a/AppConv/General/DecimalUnitConverterBase.cs b/AppConv/General/DecimalUnitConverterBase.cs new file mode 100644 index 0000000..fa40fb7 --- /dev/null +++ b/AppConv/General/DecimalUnitConverterBase.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +namespace AppConv.General{ + internal abstract class DecimalUnitConverterBase<T> : IUnitType where T : struct{ + internal sealed class DecimalFuncMap : Dictionary<T, Func<decimal, decimal>>{ + public DecimalFuncMap(){} + public DecimalFuncMap(int capacity) : base(capacity){} + } + + internal sealed class NameMap : Dictionary<string, T>{ + public NameMap(){} + public NameMap(int capacity) : base(capacity){} + } + + protected abstract NameMap Names { get; } + protected abstract DecimalFuncMap ConvertTo { get; } + protected abstract DecimalFuncMap ConvertFrom { get; } + + protected virtual int Precision{ + get{ + return 0; + } + } + + protected virtual bool CaseCheck{ + get{ + return false; + } + } + + protected virtual NumberStyles NumberStyle{ + get{ + return NumberStyles.Float & ~NumberStyles.AllowLeadingSign; + } + } + + protected virtual string ProcessSrc(string src){ + return src; + } + + protected virtual string ProcessDst(string dst){ + return dst; + } + + protected abstract bool IsValueInvalid(T value); + + protected virtual decimal Convert(decimal value, T from, T to){ + return ConvertFrom[to](ConvertTo[from](value)); + } + + protected virtual string Format(decimal value){ + if (Precision > 0){ + decimal truncated = decimal.Truncate(value); + + if (value == truncated){ + return truncated.ToString(CultureInfo.InvariantCulture); + } + } + + int decimalPlaces = Precision; + + if (Math.Abs(value) < 1M){ + double fractionalPart = (double)Math.Abs(value%1M); + int fractionalZeroCount = -(int)Math.Ceiling(Math.Log(fractionalPart, 10D)); + + decimalPlaces = Math.Min(28, fractionalZeroCount+Precision); + } + + string result = decimal.Round(value, decimalPlaces, MidpointRounding.ToEven).ToString(CultureInfo.InvariantCulture); + + if (decimalPlaces > 0){ + result = result.TrimEnd('0').TrimEnd('.'); + } + + return result; + } + + public bool TryProcess(string src, string dst, out string result){ + src = ProcessSrc(src); + dst = ProcessDst(dst); + + KeyValuePair<string, T>[] pairs = new KeyValuePair<string, T>[2]; + + for(int index = 0; index < 2; index++){ + string str = index == 0 ? src : dst; + + if (CaseCheck){ + List<KeyValuePair<string, T>> list = Names.Where(kvp => str.EndsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase) && (str.Length == kvp.Key.Length || !char.IsLetter(str[str.Length-kvp.Key.Length-1]))).ToList(); + + if (list.Count == 1){ + pairs[index] = list[0]; + } + else{ + pairs[index] = list.FirstOrDefault(kvp => str.EndsWith(kvp.Key, StringComparison.InvariantCulture)); + } + } + else{ + pairs[index] = Names.FirstOrDefault(kvp => str.EndsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase) && (str.Length == kvp.Key.Length || !char.IsLetter(str[str.Length-kvp.Key.Length-1]))); + } + + if (IsValueInvalid(pairs[index].Value)){ + result = string.Empty; + return false; + } + + if (index == 0){ + src = src.Substring(0, src.Length-pairs[index].Key.Length).TrimEnd(); + } + } + + decimal value; + + if (decimal.TryParse(src, NumberStyle, CultureInfo.InvariantCulture, out value)){ + result = Format(Convert(value, pairs[0].Value, pairs[1].Value)); + return true; + } + else{ + result = string.Empty; + return false; + } + } + } +} diff --git a/AppConv/General/DecimalUnitConverterSimple.cs b/AppConv/General/DecimalUnitConverterSimple.cs new file mode 100644 index 0000000..4e14561 --- /dev/null +++ b/AppConv/General/DecimalUnitConverterSimple.cs @@ -0,0 +1,66 @@ +using System; + +namespace AppConv.General{ + internal abstract class DecimalUnitConverterSimple<T> : DecimalUnitConverterBase<T> where T : struct{ + // ReSharper disable once StaticMemberInGenericType + private static readonly Func<decimal, decimal> FuncNoChange = val => val; + + private readonly NameMap UnitNames = new NameMap(); + private readonly DecimalFuncMap MapFrom = new DecimalFuncMap(); + private readonly DecimalFuncMap MapTo = new DecimalFuncMap(); + + private int invalidUnitObject = -1; + + protected sealed override NameMap Names{ + get{ + return UnitNames; + } + } + + protected sealed override DecimalFuncMap ConvertFrom{ + get{ + return MapFrom; + } + } + + protected sealed override DecimalFuncMap ConvertTo{ + get{ + return MapTo; + } + } + + protected override int Precision{ + get{ + return 3; + } + } + + protected override bool CaseCheck{ + get{ + return true; + } + } + + protected void AddUnit(T unitObject, params string[] names){ + foreach(string name in names){ + UnitNames.Add(name, unitObject); + } + + ConvertFrom.Add(unitObject, FuncNoChange); + ConvertTo.Add(unitObject, FuncNoChange); + } + + protected void SetUnitFactor(T unitObject, decimal factor){ + ConvertFrom[unitObject] = val => val*factor; + ConvertTo[unitObject] = val => val/factor; + } + + protected void SetInvalidUnitObject(T unitObject){ + this.invalidUnitObject = (int)(object)unitObject; + } + + protected sealed override bool IsValueInvalid(T value){ + return (int)(object)value == invalidUnitObject; + } + } +} diff --git a/AppConv/General/IUnitType.cs b/AppConv/General/IUnitType.cs new file mode 100644 index 0000000..9dcf3f7 --- /dev/null +++ b/AppConv/General/IUnitType.cs @@ -0,0 +1,5 @@ +namespace AppConv.General{ + internal interface IUnitType{ + bool TryProcess(string src, string dst, out string result); + } +} diff --git a/AppConv/Properties/AssemblyInfo.cs b/AppConv/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d6d4592 --- /dev/null +++ b/AppConv/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AppConv")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AppConv")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("485d80d3-c780-4264-ae08-b35c599aa73e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AppConv/Units/Angle.cs b/AppConv/Units/Angle.cs new file mode 100644 index 0000000..2d949ab --- /dev/null +++ b/AppConv/Units/Angle.cs @@ -0,0 +1,29 @@ +using System; +using AppConv.General; + +namespace AppConv.Units { + internal class Angle : DecimalUnitConverterSimple<Angle.Units>{ + internal enum Units{ + Invalid = 0, Degree, Radian, Gradian + } + + protected override int Precision{ + get{ + return 4; + } + } + + public Angle(){ + AddUnit(Units.Degree, "deg", "degree", "degrees", "arc degree", "arc degrees", "arcdegree", "arcdegrees", "°"); + AddUnit(Units.Radian, "rad", "radian", "radians"); + AddUnit(Units.Gradian, "grad", "grade", "gon", "gradian", "gradians"); + + SetUnitFactor(Units.Radian, (decimal)Math.PI/180M); + SetUnitFactor(Units.Gradian, 10M/9M); + + SetInvalidUnitObject(Units.Invalid); + } + + // TODO convert degree notation 15°24'9" + } +} diff --git a/AppConv/Units/Area.cs b/AppConv/Units/Area.cs new file mode 100644 index 0000000..4e4efc8 --- /dev/null +++ b/AppConv/Units/Area.cs @@ -0,0 +1,43 @@ +using AppConv.General; + +namespace AppConv.Units{ + internal class Area : DecimalUnitConverterSimple<Area.Units>{ + internal enum Units{ + Invalid = 0, SquareMM, SquareCM, SquareDM, SquareM, SquareKM, SquareMile, SquareYard, SquareFoot, SquareInch, Acre, Centiare, Deciare, Are, Decare, Hectare + } + + public Area(){ + AddUnit(Units.SquareMM, "mm2", "square mm", "square millimeter", "square millimeters", "square millimetre", "square millimetres"); + AddUnit(Units.SquareCM, "cm2", "square cm", "square centimeter", "square centimeters", "square centimetre", "square centimetres"); + AddUnit(Units.SquareDM, "dm2", "square dm", "square decimeter", "square decimeters", "square decimetre", "square decimetres"); + AddUnit(Units.SquareM, "m2", "square m", "square meter", "square meters", "square metre", "square metres"); + AddUnit(Units.SquareKM, "km2", "square km", "square kilometer", "square kilometers", "square kilometre", "square kilometres"); + AddUnit(Units.SquareMile, "mi2", "sq mi", "sq mile", "sq miles", "square mi", "square mile", "square miles"); + AddUnit(Units.SquareYard, "yd2", "sq yd", "sq yard", "sq yards", "square yd", "square yard", "square yards"); + AddUnit(Units.SquareFoot, "ft2", "sq ft", "sq foot", "sq feet", "square ft", "square foot", "square feet"); + AddUnit(Units.SquareInch, "in2", "sq in", "sq inch", "sq inches", "square in", "square inch", "square inches"); + AddUnit(Units.Acre, "ac", "acre", "acres"); + AddUnit(Units.Centiare, "ca", "centiare", "centiares"); + AddUnit(Units.Deciare, "da", "deciare", "deciares"); // da is not canon but w/e + AddUnit(Units.Are, "a", "are", "ares"); + AddUnit(Units.Decare, "daa", "decare", "decares"); + AddUnit(Units.Hectare, "ha", "hectare", "hectares"); + + SetUnitFactor(Units.SquareMM, 1E+6M); + SetUnitFactor(Units.SquareCM, 1E+4M); + SetUnitFactor(Units.SquareDM, 1E+2M); + SetUnitFactor(Units.SquareKM, 1E-6M); + SetUnitFactor(Units.SquareMile, 3.8610215854245E-7M); + SetUnitFactor(Units.SquareYard, 1.1959900463011M); + SetUnitFactor(Units.SquareFoot, 10.76391041671M); + SetUnitFactor(Units.SquareInch, 1550.0031000062M); + SetUnitFactor(Units.Acre, 2.4710538146717E-4M); + SetUnitFactor(Units.Deciare, 1E-1M); + SetUnitFactor(Units.Are, 1E-2M); + SetUnitFactor(Units.Decare, 1E-3M); + SetUnitFactor(Units.Hectare, 1E-4M); + + SetInvalidUnitObject(Units.Invalid); + } + } +} diff --git a/AppConv/Units/Length.cs b/AppConv/Units/Length.cs new file mode 100644 index 0000000..f307e53 --- /dev/null +++ b/AppConv/Units/Length.cs @@ -0,0 +1,84 @@ +using System; +using System.Globalization; +using System.Linq; +using AppConv.General; +using AppConv.Utils; + +namespace AppConv.Units{ + internal class Length : DecimalUnitConverterSimple<Length.Units>{ + internal enum Units{ + Invalid = 0, Meter, Inch, Foot, Yard, Mile + } + + private static readonly string[] NamesInch = { "in", "inch", "inches", "\"", "''" }; + private static readonly string[] NamesFoot = { "ft", "foot", "feet", "'" }; + + public Length(){ + AddUnit(Units.Meter, "m", "meter", "metre", "meters", "metres"); + AddUnit(Units.Inch, NamesInch); + AddUnit(Units.Foot, NamesFoot); + AddUnit(Units.Yard, "yd", "yard", "yards"); + AddUnit(Units.Mile, "mi", "mile", "miles"); + + SetUnitFactor(Units.Inch, 39.37007874M); + SetUnitFactor(Units.Foot, 3.280839895M); + SetUnitFactor(Units.Yard, 1.093613298M); + SetUnitFactor(Units.Mile, 0.0006213711922M); + + SetInvalidUnitObject(Units.Invalid); + + SI.AddSupport(typeof(Units), Units.Meter, new []{ "m" }, new []{ "meter", "metre", "meters", "metres" }, ConvertFrom, ConvertTo, Names); + } + + protected override string ProcessSrc(string src){ + string updatedStr = src; + + updatedStr = updatedStr.Replace("&", " "); + updatedStr = updatedStr.Replace(",", " "); + + string inchName = NamesInch.FirstOrDefault(name => src.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1); + + if (inchName == null){ + return src; + } + + int inchIndex = src.IndexOf(inchName, StringComparison.OrdinalIgnoreCase); + updatedStr = updatedStr.Remove(inchIndex, inchName.Length).Insert(inchIndex, new string(' ', inchName.Length)); + + string footName = NamesFoot.FirstOrDefault(name => updatedStr.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1); + + if (footName == null){ + return src; + } + + int footIndex = updatedStr.IndexOf(footName, StringComparison.OrdinalIgnoreCase); + updatedStr = updatedStr.Remove(footIndex, footName.Length).Insert(footIndex, new string(' ', footName.Length)); + + string[] tokens = updatedStr.Split(new char[]{ ' ' }, StringSplitOptions.RemoveEmptyEntries); + decimal[] numbers = new decimal[2]; + int numberIndex = 0; + + foreach(string token in tokens){ + decimal number; + + if (decimal.TryParse(token.Trim(), NumberStyle, CultureInfo.InvariantCulture, out number)){ + if (numberIndex < numbers.Length){ + numbers[numberIndex++] = number; + } + else{ + return src; + } + } + } + + if (numberIndex != numbers.Length){ + return src; + } + + decimal srcFeet = numbers[footIndex < inchIndex ? 0 : 1]; + decimal srcInches = numbers[inchIndex < footIndex ? 0 : 1]; + + return srcInches+srcFeet*12M+" in"; + } + } +} diff --git a/AppConv/Units/Radix.cs b/AppConv/Units/Radix.cs new file mode 100644 index 0000000..7fca362 --- /dev/null +++ b/AppConv/Units/Radix.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using AppConv.General; +using AppConv.Utils; +using Base; + +namespace AppConv.Units{ + internal class Radix : IUnitType{ + private static readonly Dictionary<string, int> RadixDescriptions = new Dictionary<string, int>{ + { "UNARY", 1 }, + { "BINARY", 2 }, + { "BIN", 2 }, + { "TERNARY", 3 }, + { "QUATERNARY", 4 }, + { "QUINARY", 5 }, + { "SENARY", 6 }, + { "OCTAL", 8 }, + { "OCT", 8 }, + { "DECIMAL", 10 }, + { "DEC", 10 }, + { "UNDECIMAL", 11 }, + { "DUODECIMAL", 12 }, + { "DOZENAL", 12 }, + { "TRIDECIMAL", 13 }, + { "TETRADECIMAL", 14 }, + { "PENTADECIMAL", 15 }, + { "HEXADECIMAL", 16 }, + { "HEX", 16 } + }; + + static Radix(){ + for(int baseNumber = 1; baseNumber <= 16; baseNumber++){ + RadixDescriptions.Add("RADIX "+baseNumber, baseNumber); + RadixDescriptions.Add("BASE "+baseNumber, baseNumber); + } + } + + public bool TryProcess(string src, string dst, out string result){ + int targetBase; + + if (!RadixDescriptions.TryGetValue(dst.ToUpperInvariant(), out targetBase)){ + result = string.Empty; + return false; + } + + string contents; + int sourceBase; + + if (!ParseSrc(src, out contents, out sourceBase)){ + result = string.Empty; + return false; + } + + if (contents[0] == '-'){ + throw new CommandException("Negative numbers are not supported."); + } + else if (!RadixConversion.IsBaseValid(sourceBase) || !RadixConversion.IsBaseValid(targetBase)){ + throw new CommandException("Only bases between 1 and 16 allowed."); + } + else if (!RadixConversion.IsNumberValid(contents, sourceBase)){ + throw new CommandException("The input is not a valid base "+sourceBase+" number: "+contents); + } + + if (sourceBase == targetBase){ + result = src; + return true; + } + + try{ + result = RadixConversion.Do(contents, sourceBase, targetBase); + }catch(OverflowException){ + throw new CommandException("The number has overflown."); + } + + return true; + } + + private static bool ParseSrc(string src, out string sourceContent, out int sourceBase){ + if (src.All(chr => chr >= '0' && chr <= '9')){ + sourceContent = src; + sourceBase = 10; + return true; + } + + string upper = src.ToUpperInvariant(); + + if (upper.StartsWith("0X")){ + sourceContent = upper.Substring(2); + sourceBase = 16; + return true; + } + + if (upper.StartsWith("0B")){ + sourceContent = upper.Substring(2); + sourceBase = 2; + return true; + } + + int fromIndex = src.IndexOf("FROM", StringComparison.InvariantCultureIgnoreCase); + + if (fromIndex != -1){ + src = src.Remove(fromIndex, 4); + } + + foreach(KeyValuePair<string, int> kvp in RadixDescriptions){ + if (src.StartsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase)){ + sourceContent = src.Substring(kvp.Key.Length).Trim(); + sourceBase = kvp.Value; + return true; + } + else if (src.EndsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase)){ + sourceContent = src.Substring(0, src.Length-kvp.Key.Length).Trim(); + sourceBase = kvp.Value; + return true; + } + } + + sourceContent = string.Empty; + sourceBase = 0; + return false; + } + } +} diff --git a/AppConv/Units/Storage.cs b/AppConv/Units/Storage.cs new file mode 100644 index 0000000..3addcdc --- /dev/null +++ b/AppConv/Units/Storage.cs @@ -0,0 +1,29 @@ +using System; +using AppConv.General; +using AppConv.Utils; + +namespace AppConv.Units { + internal class Storage : DecimalUnitConverterSimple<Storage.Units>{ + internal enum Units{ + Invalid = 0, Byte, Bit + } + + public Storage(){ + AddUnit(Units.Byte, "B", "byte", "bytes"); + AddUnit(Units.Bit, "b", "bit", "bits"); + + SetUnitFactor(Units.Bit, 8M); + + SetInvalidUnitObject(Units.Invalid); + + SI.ExtededProperties bitConversionProperties = new SI.ExtededProperties{ + FactorPredicate = factor => factor > 0 && factor%3 == 0, + FromFunctionGenerator = exponent => () => (decimal)Math.Pow(1024, -(int)(exponent/3)), + ToFunctionGenerator = exponent => () => (decimal)Math.Pow(1024, (int)(exponent/3)) + }; + + SI.AddSupportCustom(typeof(Units), Units.Byte, new []{ "B" }, new []{ "byte", "bytes" }, ConvertFrom, ConvertTo, Names, bitConversionProperties); + SI.AddSupportCustom(typeof(Units), Units.Bit, new []{ "b" }, new []{ "bit", "bits" }, ConvertFrom, ConvertTo, Names, bitConversionProperties); + } + } +} diff --git a/AppConv/Units/Temperature.cs b/AppConv/Units/Temperature.cs new file mode 100644 index 0000000..d7d7a97 --- /dev/null +++ b/AppConv/Units/Temperature.cs @@ -0,0 +1,102 @@ +using System.Globalization; +using System.Text.RegularExpressions; +using AppConv.General; +using Base.Utils; + +namespace AppConv.Units{ + internal class Temperature : DecimalUnitConverterBase<Temperature.Units>{ + internal enum Units{ + Invalid = 0, Celsius, Kelvin, Fahrenheit, Rankine, Delisle, Newton, Reaumur, Romer + } + + private static readonly NameMap UnitNames = new NameMap(21){ + { "C", Units.Celsius }, + { "Celsius", Units.Celsius }, + { "K", Units.Kelvin }, + { "Kelvin", Units.Kelvin }, + { "F", Units.Fahrenheit }, + { "Fahrenheit", Units.Fahrenheit }, + { "R", Units.Rankine }, + { "Ra", Units.Rankine }, + { "Rankine", Units.Rankine }, + { "De", Units.Delisle }, + { "Delisle", Units.Delisle }, + { "N", Units.Newton }, + { "Newton", Units.Newton }, + { "Re", Units.Reaumur }, + { "Ré", Units.Reaumur }, + { "Reaumur", Units.Reaumur }, + { "Réaumur", Units.Reaumur }, + { "Ro", Units.Romer }, + { "Rø", Units.Romer }, + { "Romer", Units.Romer }, + { "Rømer", Units.Romer } + }; + + private static readonly DecimalFuncMap FromCelsius = new DecimalFuncMap(8){ + { Units.Celsius, val => val }, + { Units.Kelvin, val => val+273.15M }, + { Units.Fahrenheit, val => val*1.8M+32M }, + { Units.Rankine, val => (val+273.15M)*1.8M }, + { Units.Delisle, val => (100M-val)*1.5M }, + { Units.Newton, val => val*0.33M }, + { Units.Reaumur, val => val*0.8M }, + { Units.Romer, val => val*0.525M+7.5M } + }; + + private static readonly DecimalFuncMap ToCelsius = new DecimalFuncMap(8){ + { Units.Celsius, val => val }, + { Units.Kelvin, val => val-273.15M }, + { Units.Fahrenheit, val => (val-32M)*5M/9M }, + { Units.Rankine, val => (val-491.67M)*5M/9M }, + { Units.Delisle, val => 100M-val*2M/3M }, + { Units.Newton, val => val*100M/33M }, + { Units.Reaumur, val => val*1.25M }, + { Units.Romer, val => (val-7.5M)*40M/21M } + }; + + private static readonly Regex RegexCleanup = new Regex("deg(?:rees?)?|°", RegexUtils.Text); + + protected override NameMap Names{ + get{ + return UnitNames; + } + } + + protected override DecimalFuncMap ConvertFrom{ + get{ + return FromCelsius; + } + } + + protected override DecimalFuncMap ConvertTo{ + get{ + return ToCelsius; + } + } + + protected override int Precision{ + get{ + return 2; + } + } + + protected override NumberStyles NumberStyle{ + get{ + return NumberStyles.Float; + } + } + + protected override string ProcessSrc(string src){ + return RegexCleanup.Replace(src, ""); + } + + protected override string ProcessDst(string dst){ + return RegexCleanup.Replace(dst, ""); + } + + protected override bool IsValueInvalid(Units value){ + return value == Units.Invalid; + } + } +} diff --git a/AppConv/Units/Volume.cs b/AppConv/Units/Volume.cs new file mode 100644 index 0000000..154b11f --- /dev/null +++ b/AppConv/Units/Volume.cs @@ -0,0 +1,28 @@ +using AppConv.General; +using AppConv.Utils; + +namespace AppConv.Units{ + internal class Volume : DecimalUnitConverterSimple<Volume.Units>{ + internal enum Units{ + Invalid = 0, Liter, CubicMM, CubicCM, CubicDM, CubicM, CubicKM + } + + public Volume(){ + AddUnit(Units.Liter, "l", "liter", "liters", "litre", "litres"); + AddUnit(Units.CubicMM, "mm3", "cubic mm", "cubic millimeter", "cubic millimeters", "cubic millimetre", "cubic millimetres"); + AddUnit(Units.CubicCM, "cm3", "cubic cm", "cubic centimeter", "cubic centimeters", "cubic centimetre", "cubic centimetres"); + AddUnit(Units.CubicDM, "dm3", "cubic dm", "cubic decimeter", "cubic decimeters", "cubic decimetre", "cubic decimetres"); + AddUnit(Units.CubicM, "m3", "cubic m", "cubic meter", "cubic meters", "cubic metre", "cubic metres"); + AddUnit(Units.CubicKM, "km3", "cubic km", "cubic kilometer", "cubic kilometers", "cubic kilometre", "cubic kilometres"); + + SetUnitFactor(Units.CubicMM, 1000000M); + SetUnitFactor(Units.CubicCM, 1000M); + SetUnitFactor(Units.CubicM, 0.001M); + SetUnitFactor(Units.CubicKM, 1E-12M); + + SetInvalidUnitObject(Units.Invalid); + + SI.AddSupport(typeof(Units), Units.Liter, new []{ "l" }, new []{ "liter", "litre", "liters", "litres" }, ConvertFrom, ConvertTo, Names); + } + } +} diff --git a/AppConv/Units/Weight.cs b/AppConv/Units/Weight.cs new file mode 100644 index 0000000..35896f8 --- /dev/null +++ b/AppConv/Units/Weight.cs @@ -0,0 +1,25 @@ +using AppConv.General; +using AppConv.Utils; + +namespace AppConv.Units { + internal class Weight : DecimalUnitConverterSimple<Weight.Units>{ + internal enum Units{ + Invalid = 0, Gram, Pound, Ounce, Stone + } + + public Weight(){ + AddUnit(Units.Gram, "g", "gram", "grams"); + AddUnit(Units.Pound, "lb", "lbs", "pound", "pounds"); + AddUnit(Units.Ounce, "oz", "ounce", "ounces"); + AddUnit(Units.Stone, "st", "stone", "stones"); + + SetUnitFactor(Units.Pound, 0.0022046226218M); + SetUnitFactor(Units.Ounce, 0.03527396195M); + SetUnitFactor(Units.Stone, 0.0001574730444177697M); + + SetInvalidUnitObject(Units.Invalid); + + SI.AddSupport(typeof(Units), Units.Gram, new []{ "g" }, new []{ "gram", "grams" }, ConvertFrom, ConvertTo, Names); + } + } +} diff --git a/AppConv/Utils/RadixConversion.cs b/AppConv/Utils/RadixConversion.cs new file mode 100644 index 0000000..dcdb4ae --- /dev/null +++ b/AppConv/Utils/RadixConversion.cs @@ -0,0 +1,78 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace AppConv.Utils{ + internal static class RadixConversion{ + private const string Characters = "0123456789ABCDEF"; + + public static bool IsBaseValid(int checkedBase){ + return checkedBase >= 1 && checkedBase <= 16; + } + + public static bool IsNumberValid(string contents, int checkedBase){ + if (checkedBase == 1){ + return contents.All(chr => chr == '1'); + } + + if (IsBaseValid(checkedBase)){ + return contents.Select(chr => Characters.IndexOf(char.ToUpper(chr))).All(index => index != -1 && index < checkedBase); + } + + return false; + } + + public static string Do(string contents, int fromBase, int toBase){ // TODO biginteger + if (fromBase == 1){ + contents = contents.Length.ToString(CultureInfo.InvariantCulture); + fromBase = 10; + } + + long wip; + + if (fromBase == 10){ + wip = long.Parse(contents, NumberStyles.None, CultureInfo.InvariantCulture); + } + else{ + wip = 0; + + for(int chr = 0; chr < contents.Length; chr++){ + int index = Characters.IndexOf(char.ToUpperInvariant(contents[chr])); + + if (index > 0){ + wip += index*(long)Math.Pow(fromBase, contents.Length-chr-1); + + if (wip < 0){ + throw new OverflowException(); + } + } + } + } + + if (toBase == 1){ + if (wip <= int.MaxValue){ + return new string('1', (int)wip); + } + else{ + throw new OverflowException(); + } + } + else if (wip < toBase){ + return Characters[(int)wip].ToString(); + } + else{ + StringBuilder converted = new StringBuilder(); + + while(wip >= toBase){ + int index = (int)(wip%toBase); + converted.Insert(0, Characters[index]); + + wip = wip/toBase; + } + + return converted.Insert(0, Characters[(int)wip]).ToString(); + } + } + } +} diff --git a/AppConv/Utils/SI.cs b/AppConv/Utils/SI.cs new file mode 100644 index 0000000..5c027e2 --- /dev/null +++ b/AppConv/Utils/SI.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using AppConv.General; + +namespace AppConv.Utils{ + internal static class SI{ + private static readonly List<Tuple<string, string, int>> Factors = new List<Tuple<string, string, int>>{ + new Tuple<string, string, int>("yotta", "Y", 24), + new Tuple<string, string, int>("zetta", "Z", 21), + new Tuple<string, string, int>("exa", "E", 18), + new Tuple<string, string, int>("peta", "P", 15), + new Tuple<string, string, int>("tera", "T", 12), + new Tuple<string, string, int>("giga", "G", 9), + new Tuple<string, string, int>("mega", "M", 6), + new Tuple<string, string, int>("kilo", "k", 3), + new Tuple<string, string, int>("hecto", "h", 2), + new Tuple<string, string, int>("deca", "da", 1), + new Tuple<string, string, int>("deci", "d", -1), + new Tuple<string, string, int>("centi", "c", -2), + new Tuple<string, string, int>("milli", "m", -3), + new Tuple<string, string, int>("micro", "μ", -6), + new Tuple<string, string, int>("nano", "n", -9), + new Tuple<string, string, int>("pico", "p", -12), + new Tuple<string, string, int>("femto", "f", -15), + new Tuple<string, string, int>("atto", "a", -18), + new Tuple<string, string, int>("zepto", "z", -21), + new Tuple<string, string, int>("yocto", "y", -24) + }; + + public static void AddSupport<T>(Type enumType, T unitObject, string[] unitShortNames, string[] unitLongNames, DecimalUnitConverterBase<T>.DecimalFuncMap funcFrom, DecimalUnitConverterBase<T>.DecimalFuncMap funcTo, DecimalUnitConverterBase<T>.NameMap nameMap) where T : struct{ + int enumCounter = 1000+Factors.Count*(int)(object)unitObject; + + Func<decimal, decimal> convertFrom = funcFrom[unitObject]; + Func<decimal, decimal> convertTo = funcTo[unitObject]; + + foreach(Tuple<string, string, int> factor in Factors){ + T enumObject = (T)(object)enumCounter++; + int exponent = factor.Item3; + + foreach(string unitShortName in unitShortNames){ + nameMap.Add(factor.Item2+unitShortName, enumObject); + } + + foreach(string unitLongName in unitLongNames){ + nameMap.Add(factor.Item1+unitLongName, enumObject); + } + + funcFrom.Add(enumObject, val => convertFrom(val)*(decimal)Math.Pow(10, -exponent)); + funcTo.Add(enumObject, val => convertTo(val)*(decimal)Math.Pow(10, exponent)); + } + } + + public static void AddSupportCustom<T>(Type enumType, T unitObject, string[] unitShortNames, string[] unitLongNames, DecimalUnitConverterBase<T>.DecimalFuncMap funcFrom, DecimalUnitConverterBase<T>.DecimalFuncMap funcTo, DecimalUnitConverterBase<T>.NameMap nameMap, ExtededProperties extendedProps) where T : struct{ + int enumCounter = 1000+Factors.Count*(int)(object)unitObject; + + Func<decimal, decimal> convertFrom = funcFrom[unitObject]; + Func<decimal, decimal> convertTo = funcTo[unitObject]; + + foreach(Tuple<string, string, int> factor in Factors){ + if (extendedProps.FactorPredicate != null && !extendedProps.FactorPredicate(factor.Item3)){ + continue; + } + + T enumObject = (T)(object)enumCounter++; + int exponent = factor.Item3; + + foreach(string unitShortName in unitShortNames){ + nameMap.Add(factor.Item2+unitShortName, enumObject); + } + + foreach(string unitLongName in unitLongNames){ + nameMap.Add(factor.Item1+unitLongName, enumObject); + } + + Func<decimal> genFrom = extendedProps.FromFunctionGenerator(exponent); + Func<decimal> genTo = extendedProps.ToFunctionGenerator(exponent); + + funcFrom.Add(enumObject, val => convertFrom(val)*genFrom()); + funcTo.Add(enumObject, val => convertTo(val)*genTo()); + } + } + + internal class ExtededProperties{ + public Predicate<int> FactorPredicate { get; set; } + public Func<int, Func<decimal>> FromFunctionGenerator { get; set; } + public Func<int, Func<decimal>> ToFunctionGenerator { get; set; } + } + } +} diff --git a/AppMeme/App.cs b/AppMeme/App.cs new file mode 100644 index 0000000..e85740a --- /dev/null +++ b/AppMeme/App.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using Base; + +namespace AppMeme{ + public sealed class App : IApp{ + private static readonly Dictionary<string, string> Map = new Dictionary<string, string>{ + { "shrug", @"¯\_(ツ)_/¯" }, + { "lenny", @"( ͡° ͜ʖ ͡°)" }, + { "flip", @"(╯°□°)╯︵ ┻━┻" }, + { "tableflip", @"(╯°□°)╯︵ ┻━┻" } + }; + + public string[] RecognizedNames => new string[]{ + "meme" + }; + + public MatchConfidence GetConfidence(Command cmd){ + return Map.ContainsKey(cmd.Text) ? MatchConfidence.Full : MatchConfidence.None; + } + + public string ProcessCommand(Command cmd){ + return Map[cmd.Text]; + } + } +} diff --git a/AppMeme/AppMeme.csproj b/AppMeme/AppMeme.csproj new file mode 100644 index 0000000..2bee676 --- /dev/null +++ b/AppMeme/AppMeme.csproj @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{4E27ADC4-FCBE-451E-A1F9-8050DA22A6E1}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>AppMeme</RootNamespace> + <AssemblyName>AppMeme</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>none</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + </ItemGroup> + <ItemGroup> + <Compile Include="App.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Base\Base.csproj"> + <Project>{66CF4F71-50DD-4C65-AB96-35D1193FFB50}</Project> + <Name>Base</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file diff --git a/AppMeme/Properties/AssemblyInfo.cs b/AppMeme/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..874cb7e --- /dev/null +++ b/AppMeme/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AppMeme")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AppMeme")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("6665ef00-1862-4afd-8172-a2c1d0d98141")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AppWindows/App.cs b/AppWindows/App.cs new file mode 100644 index 0000000..bd44abd --- /dev/null +++ b/AppWindows/App.cs @@ -0,0 +1,26 @@ +using System.Linq; +using AppSys.Handlers; +using Base; + +namespace AppSys{ + public sealed class App : IApp{ + private static readonly IHandler[] Handlers = { + new HandlerProcesses(), + new HandlerApps() + }; + + public string[] RecognizedNames => new string[]{ + "sys", + "os", + "win" + }; + + public MatchConfidence GetConfidence(Command cmd){ + return Handlers.Any(handler => handler.Matches(cmd)) ? MatchConfidence.Full : MatchConfidence.None; + } + + public string ProcessCommand(Command cmd){ + return Handlers.First(handler => handler.Matches(cmd)).Handle(cmd); + } + } +} diff --git a/AppWindows/AppSys.csproj b/AppWindows/AppSys.csproj new file mode 100644 index 0000000..f2a8257 --- /dev/null +++ b/AppWindows/AppSys.csproj @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{E71AFA58-A144-4170-AF7B-05730C04CF59}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>AppSys</RootNamespace> + <AssemblyName>AppSys</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>none</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <UseVSHostingProcess>false</UseVSHostingProcess> + <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + </ItemGroup> + <ItemGroup> + <Compile Include="App.cs" /> + <Compile Include="Handlers\HandlerApps.cs" /> + <Compile Include="Handlers\HandlerProcesses.cs" /> + <Compile Include="IHandler.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Base\Base.csproj"> + <Project>{66CF4F71-50DD-4C65-AB96-35D1193FFB50}</Project> + <Name>Base</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file diff --git a/AppWindows/Handlers/HandlerApps.cs b/AppWindows/Handlers/HandlerApps.cs new file mode 100644 index 0000000..7fcabba --- /dev/null +++ b/AppWindows/Handlers/HandlerApps.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using Base; + +namespace AppSys.Handlers { + internal class HandlerApps : IHandler{ + private static readonly string PathSystem = Environment.GetFolderPath(Environment.SpecialFolder.System); + + private static readonly Dictionary<string, ProcessStartInfo> Mappings = new Dictionary<string, ProcessStartInfo>{ + { "audio", new ProcessStartInfo{ + FileName = Path.Combine(PathSystem, "control.exe"), + Arguments = "mmsys.cpl" + } }, + + { "programs", new ProcessStartInfo{ + FileName = Path.Combine(PathSystem, "control.exe"), + Arguments = "appwiz.cpl" + } }, + + { "system", new ProcessStartInfo{ + FileName = Path.Combine(PathSystem, "control.exe"), + Arguments = "sysdm.cpl" + } }, + + { "environment", new ProcessStartInfo{ + FileName = Path.Combine(PathSystem, "rundll32.exe"), + Arguments = "sysdm.cpl,EditEnvironmentVariables" + } } + }; + + private static readonly Dictionary<string, string> Substitutions = new Dictionary<string, string>{ + { "sounds", "audio" }, + { "apps", "programs" }, + { "appwiz", "programs" }, + { "env", "environment" }, + { "envvars", "environment" }, + { "vars", "environment" }, + { "variables", "environment" } + }; + + public bool Matches(Command cmd){ + return Mappings.ContainsKey(cmd.Text) || Substitutions.ContainsKey(cmd.Text); + } + + public string Handle(Command cmd){ + string key; + + if (!Substitutions.TryGetValue(cmd.Text, out key)){ + key = cmd.Text; + } + + using(Process.Start(Mappings[key])){} + return null; + } + } +} diff --git a/AppWindows/Handlers/HandlerProcesses.cs b/AppWindows/Handlers/HandlerProcesses.cs new file mode 100644 index 0000000..68ced96 --- /dev/null +++ b/AppWindows/Handlers/HandlerProcesses.cs @@ -0,0 +1,49 @@ +using System; +using System.Diagnostics; +using System.Text; +using Base; + +namespace AppSys.Handlers{ + internal class HandlerProcesses : IHandler{ + public bool Matches(Command cmd){ + return cmd.Text.StartsWith("kill ", StringComparison.InvariantCultureIgnoreCase); + } + + public string Handle(Command cmd){ + string[] processNames = cmd.Text.Substring("kill ".Length).Split(',', ';'); + int succeeded = 0, failed = 0; + + foreach(string processName in processNames){ + try{ + Process[] processes = Process.GetProcessesByName(processName.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase) ? processName.Substring(0, processName.Length-4) : processName); + + foreach(Process process in processes){ + try{ + process.Kill(); + ++succeeded; + }catch{ + ++failed; + } + + process.Close(); + } + }catch{ + ++failed; + } + } + + if (succeeded == 0 && failed == 0 && (cmd.Text.Equals("kill me", StringComparison.InvariantCultureIgnoreCase) || cmd.Text.StartsWith("kill me ", StringComparison.InvariantCultureIgnoreCase) || cmd.Text.StartsWith("kill me,", StringComparison.InvariantCultureIgnoreCase))){ + return "No."; + } + + StringBuilder build = new StringBuilder(); + build.Append("Killed ").Append(succeeded).Append(" process").Append(succeeded == 1 ? "" : "es"); + + if (failed > 0){ + build.Append(", failed ").Append(failed); + } + + return build.Append('.').ToString(); + } + } +} diff --git a/AppWindows/IHandler.cs b/AppWindows/IHandler.cs new file mode 100644 index 0000000..f0f0710 --- /dev/null +++ b/AppWindows/IHandler.cs @@ -0,0 +1,8 @@ +using Base; + +namespace AppSys{ + internal interface IHandler{ + bool Matches(Command cmd); + string Handle(Command cmd); + } +} diff --git a/AppWindows/Properties/AssemblyInfo.cs b/AppWindows/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..94ccb76 --- /dev/null +++ b/AppWindows/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AppSys")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AppSys")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a4e72ee4-e061-487f-a663-165aca805e55")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Base/Base.csproj b/Base/Base.csproj new file mode 100644 index 0000000..80bb6e8 --- /dev/null +++ b/Base/Base.csproj @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{66CF4F71-50DD-4C65-AB96-35D1193FFB50}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Base</RootNamespace> + <AssemblyName>Base</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>none</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Command.cs" /> + <Compile Include="CommandEventArgs.cs" /> + <Compile Include="CommandException.cs" /> + <Compile Include="IApp.cs" /> + <Compile Include="MatchConfidence.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Utils\RegexUtils.cs" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file diff --git a/Base/Command.cs b/Base/Command.cs new file mode 100644 index 0000000..d358b2b --- /dev/null +++ b/Base/Command.cs @@ -0,0 +1,44 @@ +using System.Linq; +using System.Text.RegularExpressions; +using Base.Utils; + +namespace Base{ + public sealed class Command{ + private static readonly Regex RegexBalancedBrackets = new Regex(RegexUtils.Balance(@"\[", @"\]"), RegexOptions.Compiled); + private static readonly Regex RegexBalancedParentheses = new Regex(RegexUtils.Balance(@"\(", @"\)"), RegexOptions.Compiled); + + public string Text { get; private set; } + + public string PotentialAppName{ + get{ + int firstSpace = Text.IndexOf(' '); + + if (firstSpace == -1){ + return null; + } + + string firstToken = Text.Substring(0, firstSpace); + + if (!firstToken.All(char.IsLetter)){ + return null; + } + + return firstToken; + } + } + + public bool IsSingleToken{ + get{ + return Text.IndexOf(' ') == -1; + } + } + + public Command(string text){ + this.Text = text; + } + + public Command ReplaceBrackets(MatchEvaluator evaluator){ + return new Command(RegexBalancedParentheses.Replace(RegexBalancedBrackets.Replace(Text, evaluator), evaluator)); + } + } +} diff --git a/Base/CommandEventArgs.cs b/Base/CommandEventArgs.cs new file mode 100644 index 0000000..8afae24 --- /dev/null +++ b/Base/CommandEventArgs.cs @@ -0,0 +1,11 @@ +using System; + +namespace Base{ + public class CommandEventArgs : EventArgs{ + public Command Command { get; private set; } + + public CommandEventArgs(string text){ + this.Command = new Command(text); + } + } +} diff --git a/Base/CommandException.cs b/Base/CommandException.cs new file mode 100644 index 0000000..58aa207 --- /dev/null +++ b/Base/CommandException.cs @@ -0,0 +1,8 @@ +using System; + +namespace Base{ + public class CommandException : Exception{ + public CommandException(string message) : base(message){} + public CommandException(string message, Exception innerException) : base(message,innerException){} + } +} diff --git a/Base/IApp.cs b/Base/IApp.cs new file mode 100644 index 0000000..57a8a50 --- /dev/null +++ b/Base/IApp.cs @@ -0,0 +1,8 @@ +namespace Base{ + public interface IApp{ + string[] RecognizedNames { get; } + + MatchConfidence GetConfidence(Command cmd); + string ProcessCommand(Command cmd); + } +} diff --git a/Base/MatchConfidence.cs b/Base/MatchConfidence.cs new file mode 100644 index 0000000..82b53e3 --- /dev/null +++ b/Base/MatchConfidence.cs @@ -0,0 +1,8 @@ +namespace Base{ + public enum MatchConfidence{ + None = 0, + Low = 1, + Possible = 2, + Full = 3 + } +} diff --git a/Base/Properties/AssemblyInfo.cs b/Base/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..bfb38eb --- /dev/null +++ b/Base/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Base")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Base")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f7bbfcb0-16a1-47e4-9adb-515cb6d9e5af")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Base/Utils/RegexUtils.cs b/Base/Utils/RegexUtils.cs new file mode 100644 index 0000000..d02b754 --- /dev/null +++ b/Base/Utils/RegexUtils.cs @@ -0,0 +1,23 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace Base.Utils{ + public static class RegexUtils{ + public static readonly RegexOptions Text = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled; + + public static string Balance(string escapedStart, string escapedEnd){ // \(((?>[^()]+|\((?<n>)|\)(?<-n>))+(?(n)(?!)))\) + return new StringBuilder() + .Append(escapedStart) + .Append(@"((?>[^") + .Append(escapedStart) + .Append(escapedEnd) + .Append(@"]+|") + .Append(escapedStart) + .Append(@"(?<n>)|") + .Append(escapedEnd) + .Append(@"(?<-n>))+(?(n)(?!)))") + .Append(escapedEnd) + .ToString(); + } + } +} diff --git a/Query.sln b/Query.sln new file mode 100644 index 0000000..4960893 --- /dev/null +++ b/Query.sln @@ -0,0 +1,60 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Query", "Query\Query.csproj", "{1A2176AF-3885-4619-8F85-4C751A5ABA8F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Base", "Base\Base.csproj", "{66CF4F71-50DD-4C65-AB96-35D1193FFB50}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{6434DC0B-7270-4002-857B-53F8839C9CA6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppCalc", "AppCalc\AppCalc.csproj", "{C7A21640-CAF3-40E8-AA6A-793181BD28AA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppConv", "AppConv\AppConv.csproj", "{1AC5280A-81D1-4E02-9122-DB358734FFB4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppMeme", "AppMeme\AppMeme.csproj", "{4E27ADC4-FCBE-451E-A1F9-8050DA22A6E1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppSys", "AppWindows\AppSys.csproj", "{E71AFA58-A144-4170-AF7B-05730C04CF59}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1A2176AF-3885-4619-8F85-4C751A5ABA8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A2176AF-3885-4619-8F85-4C751A5ABA8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A2176AF-3885-4619-8F85-4C751A5ABA8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A2176AF-3885-4619-8F85-4C751A5ABA8F}.Release|Any CPU.Build.0 = Release|Any CPU + {66CF4F71-50DD-4C65-AB96-35D1193FFB50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {66CF4F71-50DD-4C65-AB96-35D1193FFB50}.Debug|Any CPU.Build.0 = Debug|Any CPU + {66CF4F71-50DD-4C65-AB96-35D1193FFB50}.Release|Any CPU.ActiveCfg = Release|Any CPU + {66CF4F71-50DD-4C65-AB96-35D1193FFB50}.Release|Any CPU.Build.0 = Release|Any CPU + {C7A21640-CAF3-40E8-AA6A-793181BD28AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7A21640-CAF3-40E8-AA6A-793181BD28AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7A21640-CAF3-40E8-AA6A-793181BD28AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7A21640-CAF3-40E8-AA6A-793181BD28AA}.Release|Any CPU.Build.0 = Release|Any CPU + {1AC5280A-81D1-4E02-9122-DB358734FFB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1AC5280A-81D1-4E02-9122-DB358734FFB4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1AC5280A-81D1-4E02-9122-DB358734FFB4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1AC5280A-81D1-4E02-9122-DB358734FFB4}.Release|Any CPU.Build.0 = Release|Any CPU + {4E27ADC4-FCBE-451E-A1F9-8050DA22A6E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E27ADC4-FCBE-451E-A1F9-8050DA22A6E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E27ADC4-FCBE-451E-A1F9-8050DA22A6E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E27ADC4-FCBE-451E-A1F9-8050DA22A6E1}.Release|Any CPU.Build.0 = Release|Any CPU + {E71AFA58-A144-4170-AF7B-05730C04CF59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E71AFA58-A144-4170-AF7B-05730C04CF59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E71AFA58-A144-4170-AF7B-05730C04CF59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E71AFA58-A144-4170-AF7B-05730C04CF59}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C7A21640-CAF3-40E8-AA6A-793181BD28AA} = {6434DC0B-7270-4002-857B-53F8839C9CA6} + {1AC5280A-81D1-4E02-9122-DB358734FFB4} = {6434DC0B-7270-4002-857B-53F8839C9CA6} + {4E27ADC4-FCBE-451E-A1F9-8050DA22A6E1} = {6434DC0B-7270-4002-857B-53F8839C9CA6} + {E71AFA58-A144-4170-AF7B-05730C04CF59} = {6434DC0B-7270-4002-857B-53F8839C9CA6} + EndGlobalSection +EndGlobal diff --git a/Query/Controls/QueryHistoryLog.Designer.cs b/Query/Controls/QueryHistoryLog.Designer.cs new file mode 100644 index 0000000..2858324 --- /dev/null +++ b/Query/Controls/QueryHistoryLog.Designer.cs @@ -0,0 +1,57 @@ +namespace Query.Controls { + partial class QueryHistoryLog { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() { + this.container = new System.Windows.Forms.FlowLayoutPanel(); + this.SuspendLayout(); + // + // container + // + this.container.AutoScroll = true; + this.container.Dock = System.Windows.Forms.DockStyle.Fill; + this.container.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; + this.container.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); + this.container.Location = new System.Drawing.Point(0, 0); + this.container.Name = "container"; + this.container.Size = new System.Drawing.Size(150, 150); + this.container.TabIndex = 0; + this.container.WrapContents = false; + // + // QueryHistoryLog + // + this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 22F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Controls.Add(this.container); + this.Font = new System.Drawing.Font("Consolas", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238))); + this.Name = "QueryHistoryLog"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.FlowLayoutPanel container; + } +} diff --git a/Query/Controls/QueryHistoryLog.cs b/Query/Controls/QueryHistoryLog.cs new file mode 100644 index 0000000..2859b71 --- /dev/null +++ b/Query/Controls/QueryHistoryLog.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +namespace Query.Controls{ + sealed partial class QueryHistoryLog : UserControl{ + public enum EntryType{ + UserInput, CommandResult, Information, Error + } + + private static readonly Dictionary<EntryType, Color> EntryColorMap = new Dictionary<EntryType, Color>{ + { EntryType.UserInput, Color.FromArgb(160, 160, 160) }, + { EntryType.CommandResult, Color.FromArgb(240, 240, 240) }, + { EntryType.Information, Color.FromArgb(160, 255, 140) }, + { EntryType.Error, Color.FromArgb(255, 40, 40) } + }; + + public QueryHistoryLog(){ + InitializeComponent(); + } + + public void AddEntry(string text, EntryType type){ + int width = container.Width-SystemInformation.VerticalScrollBarWidth; + + Label label = new Label{ + AutoSize = true, + Font = container.Font, + ForeColor = EntryColorMap[type], + Text = text, + Margin = new Padding(0,1,0,1), + MaximumSize = new Size(width, 0), + Width = width + }; + + container.Controls.Add(label); + container.AutoScrollPosition = new Point(0, container.VerticalScroll.Maximum); + } + + public void ClearEntries(){ + container.Controls.Clear(); + } + } +} diff --git a/Query/Controls/QueryTextBox.Designer.cs b/Query/Controls/QueryTextBox.Designer.cs new file mode 100644 index 0000000..46234f2 --- /dev/null +++ b/Query/Controls/QueryTextBox.Designer.cs @@ -0,0 +1,61 @@ +namespace Query.Controls { + partial class QueryTextBox { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() { + this.tb = new CustomTextBox(); + this.SuspendLayout(); + // + // tb + // + this.tb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tb.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(36)))), ((int)(((byte)(36)))), ((int)(((byte)(36))))); + this.tb.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.tb.Font = new System.Drawing.Font("Consolas", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238))); + this.tb.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); + this.tb.Location = new System.Drawing.Point(5, 6); + this.tb.Margin = new System.Windows.Forms.Padding(5); + this.tb.Name = "tb"; + this.tb.Size = new System.Drawing.Size(509, 23); + this.tb.TabIndex = 0; + // + // QueryTextBox + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(36)))), ((int)(((byte)(36)))), ((int)(((byte)(36))))); + this.Controls.Add(this.tb); + this.Name = "QueryTextBox"; + this.Size = new System.Drawing.Size(519, 33); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private CustomTextBox tb; + } +} diff --git a/Query/Controls/QueryTextBox.cs b/Query/Controls/QueryTextBox.cs new file mode 100644 index 0000000..38a2013 --- /dev/null +++ b/Query/Controls/QueryTextBox.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; +using Base; +using Query.Core; + +namespace Query.Controls{ + sealed partial class QueryTextBox : UserControl{ + public event EventHandler<CommandEventArgs> CommandRan; + + private CommandHistory history; + private Action<string> log; + + public QueryTextBox(){ + InitializeComponent(); + } + + public void Setup(CommandHistory historyObj, Action<string> logFunc){ + this.history = historyObj; + this.log = logFunc; + } + + private void OnCommandRan(){ + CommandRan?.Invoke(this, new CommandEventArgs(tb.Text)); + } + + private sealed class CustomTextBox : TextBox{ + private string lastInputStr = string.Empty; + private int lastInputPos = 0; + + private bool doResetHistoryMemory; + private bool lastArrowShift; + private int historyOffset; + + public CustomTextBox(){ + TextChanged += CustomTextBox_TextChanged; + } + + protected override void OnKeyDown(KeyEventArgs e){ + QueryTextBox input = (QueryTextBox)Parent; + CommandHistory history = input.history; + + Keys key = e.KeyCode; + bool handled = false; + + switch(key){ + case Keys.Enter: + if (Text != string.Empty){ + input.OnCommandRan(); + + Text = string.Empty; + doResetHistoryMemory = true; + handled = true; + } + + break; + + case Keys.Up: + if (lastArrowShift != e.Shift){ + lastArrowShift = e.Shift; + historyOffset = 0; + } + + --historyOffset; + + if (InsertFromHistory(e.Shift ? history.Results : history.Queries)){ + ++historyOffset; + } + + handled = true; + break; + + case Keys.Down: + if (lastArrowShift != e.Shift){ + lastArrowShift = e.Shift; + historyOffset = 0; + } + + ++historyOffset; + + if (InsertFromHistory(e.Shift ? history.Results : history.Queries)){ + --historyOffset; + } + + handled = true; + break; + + case Keys.C: + if (e.Modifiers == Keys.Control){ + if (SelectionLength == 0 && history.Results.Count > 0){ + Clipboard.SetText(history.Results.Last(), TextDataFormat.UnicodeText); + input.log("Copied to clipboard."); + handled = true; + } + } + + break; + } + + if (!handled && key != Keys.ControlKey && key != Keys.ShiftKey && key != Keys.Menu){ + doResetHistoryMemory = true; + } + + e.Handled = e.SuppressKeyPress = handled; + base.OnKeyDown(e); + } + + protected override void OnKeyUp(KeyEventArgs e){ + base.OnKeyUp(e); + + if (doResetHistoryMemory){ + doResetHistoryMemory = false; + ResetHistoryMemory(); + } + } + + private void CustomTextBox_TextChanged(object sender, EventArgs e){ + ResetHistoryMemory(); + } + + // Management + + private void ResetHistoryMemory(){ + lastInputStr = Text; + lastInputPos = SelectionStart; + historyOffset = 0; + } + + private bool InsertFromHistory(IList<string> collection){ + if (collection.Count == 0){ + return true; + } + + int index = collection.Count + historyOffset; + bool wasClamped = false; + + if (index < 0){ + index = 0; + wasClamped = true; + } + else if (index >= collection.Count){ + index = collection.Count - 1; + wasClamped = true; + } + + TextChanged -= CustomTextBox_TextChanged; + + Text = lastInputStr.Insert(lastInputPos, collection[index]); + SelectionStart = lastInputPos + collection[index].Length; + SelectionLength = 0; + + TextChanged += CustomTextBox_TextChanged; + return wasClamped; + } + } + } +} diff --git a/Query/Core/CommandHistory.cs b/Query/Core/CommandHistory.cs new file mode 100644 index 0000000..e715949 --- /dev/null +++ b/Query/Core/CommandHistory.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; + +namespace Query.Core{ + sealed class CommandHistory{ + private readonly List<string> queries = new List<string>(); + private readonly List<string> results = new List<string>(); + + public IList<string> Queries{ + get{ + return queries; + } + } + + public IList<string> Results{ + get{ + return results; + } + } + + public void AddQuery(string text){ + queries.Add(text); + } + + public void AddResult(string text){ + results.Add(text); + } + + public void Clear(){ + queries.Clear(); + results.Clear(); + } + } +} diff --git a/Query/Core/CommandProcessor.cs b/Query/Core/CommandProcessor.cs new file mode 100644 index 0000000..2c1b912 --- /dev/null +++ b/Query/Core/CommandProcessor.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Base; + +namespace Query.Core{ + sealed class CommandProcessor{ + private readonly Dictionary<string, IApp> appNames = new Dictionary<string, IApp>(8); + private readonly HashSet<IApp> appSet = new HashSet<IApp>(); + + public Func<string, bool> SingleTokenProcessor { get; set; } + + public void AddApp<T>() where T : IApp, new(){ + IApp app = new T(); + + foreach(string name in app.RecognizedNames){ + appNames.Add(name, app); + appSet.Add(app); + } + } + + public string Run(Command cmd){ + cmd = cmd.ReplaceBrackets(match => Run(new Command(match.Groups[1].Value))); + + string appName = cmd.PotentialAppName; + IApp app; + + if (appName != null && appNames.TryGetValue(appName.ToLowerInvariant(), out app)){ + return app.ProcessCommand(new Command(cmd.Text.Substring(appName.Length+1))); + } + + if (cmd.IsSingleToken && SingleTokenProcessor != null && SingleTokenProcessor(cmd.Text)){ + return null; + } + + var list = appSet.Select(iapp => new { App = iapp, Confidence = iapp.GetConfidence(cmd) }).OrderByDescending(obj => obj.Confidence).Where(obj => obj.Confidence != MatchConfidence.None).ToList(); + + if (list.Count == 0){ + throw new CommandException("Could not find any suitable app, please write the app name and press Up Arrow."); + } + else if (list.Count == 1){ + app = list[0].App; + } + else{ + List<IApp> plausible = new List<IApp>{ list[0].App }; + MatchConfidence topConfidence = list[0].Confidence; + + for(int index = 1; index < list.Count; index++){ + if (list[index].Confidence == topConfidence){ + plausible.Add(list[index].App); + } + } + + if (plausible.Count == 1){ + app = plausible.First(); + } + else{ + throw new CommandException("Command is ambiguous, please write the app name and press Up Arrow. Suggested apps: "+string.Join(", ",plausible.Select(iapp => iapp.RecognizedNames.First()))); + } + } + + return app.ProcessCommand(cmd); + } + } +} diff --git a/Query/Core/KeyboardHook.cs b/Query/Core/KeyboardHook.cs new file mode 100644 index 0000000..c282263 --- /dev/null +++ b/Query/Core/KeyboardHook.cs @@ -0,0 +1,64 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace Query.Core{ + sealed class KeyboardHook{ + public event EventHandler Triggered; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly NativeMethods.HookProc keyboardHookDelegate; + private IntPtr keyboardHook; + + public KeyboardHook(){ + keyboardHookDelegate = KeyboardHookProc; + } + + public void StartHook(){ + if (keyboardHook != IntPtr.Zero){ + NativeMethods.UnhookWindowsHookEx(keyboardHook); + } + + keyboardHook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_KEYBOARD_LL, keyboardHookDelegate, IntPtr.Zero, 0); + } + + public void StopHook(){ + if (keyboardHook != IntPtr.Zero){ + NativeMethods.UnhookWindowsHookEx(keyboardHook); + keyboardHook = IntPtr.Zero; + } + } + + private IntPtr KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam){ + if (wParam == (IntPtr)NativeMethods.WM_KEYDOWN){ + Keys key = (Keys)Marshal.ReadInt32(lParam); + + if ((key == Keys.LWin || key == Keys.RWin) && Control.ModifierKeys.HasFlag(Keys.Control)){ + Triggered?.Invoke(this, EventArgs.Empty); + return NativeMethods.HookHandled; + } + } + + return NativeMethods.CallNextHookEx(keyboardHook, nCode, wParam, lParam); + } + + private static class NativeMethods{ + public const int WH_KEYBOARD_LL = 13; + public const int WM_KEYDOWN = 0x0100; + public const int WM_KEYUP = 0x0101; + + public static readonly IntPtr HookHandled = new IntPtr(-1); + + public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll")] + public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); + + [DllImport("user32.dll")] + public static extern bool UnhookWindowsHookEx(IntPtr idHook); + + [DllImport("user32.dll")] + public static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam); + } + } +} diff --git a/Query/MainForm.Designer.cs b/Query/MainForm.Designer.cs new file mode 100644 index 0000000..90b7ad0 --- /dev/null +++ b/Query/MainForm.Designer.cs @@ -0,0 +1,135 @@ +namespace Query { + partial class MainForm { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.queryLog = new Query.Controls.QueryHistoryLog(); + this.queryBox = new Query.Controls.QueryTextBox(); + this.trayIcon = new System.Windows.Forms.NotifyIcon(this.components); + this.contextMenuTray = new System.Windows.Forms.ContextMenuStrip(this.components); + this.showToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.hookToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.contextMenuTray.SuspendLayout(); + this.SuspendLayout(); + // + // queryLog + // + this.queryLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.queryLog.BackColor = System.Drawing.Color.Transparent; + this.queryLog.Font = new System.Drawing.Font("Consolas", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238))); + this.queryLog.Location = new System.Drawing.Point(5, 5); + this.queryLog.Margin = new System.Windows.Forms.Padding(5); + this.queryLog.Name = "queryLog"; + this.queryLog.Size = new System.Drawing.Size(522, 192); + this.queryLog.TabIndex = 1; + // + // queryBox + // + this.queryBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.queryBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(36)))), ((int)(((byte)(36)))), ((int)(((byte)(36))))); + this.queryBox.Location = new System.Drawing.Point(0, 202); + this.queryBox.Margin = new System.Windows.Forms.Padding(0); + this.queryBox.Name = "queryBox"; + this.queryBox.Size = new System.Drawing.Size(532, 33); + this.queryBox.TabIndex = 0; + // + // trayIcon + // + this.trayIcon.ContextMenuStrip = this.contextMenuTray; + this.trayIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("trayIcon.Icon"))); + this.trayIcon.Text = "Query"; + this.trayIcon.Visible = true; + this.trayIcon.Click += new System.EventHandler(this.trayIcon_Click); + // + // contextMenuTray + // + this.contextMenuTray.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.showToolStripMenuItem, + this.hookToolStripMenuItem, + this.exitToolStripMenuItem}); + this.contextMenuTray.Name = "contextMenuTray"; + this.contextMenuTray.ShowImageMargin = false; + this.contextMenuTray.ShowItemToolTips = false; + this.contextMenuTray.Size = new System.Drawing.Size(128, 92); + // + // showToolStripMenuItem + // + this.showToolStripMenuItem.Name = "showToolStripMenuItem"; + this.showToolStripMenuItem.Size = new System.Drawing.Size(127, 22); + this.showToolStripMenuItem.Text = "Show"; + this.showToolStripMenuItem.Click += new System.EventHandler(this.showToolStripMenuItem_Click); + // + // hookToolStripMenuItem + // + this.hookToolStripMenuItem.Name = "hookToolStripMenuItem"; + this.hookToolStripMenuItem.Size = new System.Drawing.Size(127, 22); + this.hookToolStripMenuItem.Text = "Hook"; + this.hookToolStripMenuItem.Click += new System.EventHandler(this.hookToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(127, 22); + this.exitToolStripMenuItem.Text = "Exit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.ClientSize = new System.Drawing.Size(532, 235); + this.ControlBox = false; + this.Controls.Add(this.queryLog); + this.Controls.Add(this.queryBox); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "MainForm"; + this.ShowInTaskbar = false; + this.Text = "Query"; + this.Deactivate += new System.EventHandler(this.MainForm_Deactivate); + this.Shown += new System.EventHandler(this.MainForm_Shown); + this.contextMenuTray.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private Query.Controls.QueryTextBox queryBox; + private Controls.QueryHistoryLog queryLog; + private System.Windows.Forms.NotifyIcon trayIcon; + private System.Windows.Forms.ContextMenuStrip contextMenuTray; + private System.Windows.Forms.ToolStripMenuItem showToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem hookToolStripMenuItem; + } +} \ No newline at end of file diff --git a/Query/MainForm.cs b/Query/MainForm.cs new file mode 100644 index 0000000..60c7c1d --- /dev/null +++ b/Query/MainForm.cs @@ -0,0 +1,146 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using Base; +using Query.Controls; +using Query.Core; + +namespace Query{ + partial class MainForm : Form{ + private readonly CommandProcessor processor; + private readonly CommandHistory history; + + private readonly Timer focusTimer; + private readonly KeyboardHook keyboardHook; + + private bool isLoaded; + + public MainForm(){ + InitializeComponent(); + + processor = new CommandProcessor{ + SingleTokenProcessor = ProcessSingleToken + }; + + processor.AddApp<AppCalc.App>(); + processor.AddApp<AppConv.App>(); + processor.AddApp<AppMeme.App>(); + processor.AddApp<AppSys.App>(); + + history = new CommandHistory(); + queryBox.Setup(history, str => queryLog.AddEntry(str, QueryHistoryLog.EntryType.Information)); + + keyboardHook = new KeyboardHook(); + keyboardHook.Triggered += keyboardHook_Triggered; + + focusTimer = new Timer{ + Interval = 1 + }; + + focusTimer.Tick += focusTimer_Tick; + + Disposed += MainForm_Disposed; + queryBox.CommandRan += queryBox_CommandRan; + } + + private void SetShown(bool show){ + if (show){ + focusTimer.Start(); + } + else{ + Hide(); + } + } + + private void MainForm_Shown(object sender, EventArgs e){ + Rectangle screenRect = Screen.PrimaryScreen.WorkingArea; + Location = new Point(screenRect.X + screenRect.Width - Width, screenRect.Y + screenRect.Height - Height); + + if (!isLoaded){ + isLoaded = true; + keyboardHook.StartHook(); + } + } + + private void MainForm_Deactivate(object sender, EventArgs e){ + SetShown(false); + } + + private void MainForm_Disposed(object sender, EventArgs e){ + keyboardHook.StopHook(); + } + + private void trayIcon_Click(object sender, EventArgs e){ + if (((MouseEventArgs)e).Button == MouseButtons.Left){ + SetShown(true); + } + } + + private void showToolStripMenuItem_Click(object sender, EventArgs e){ + SetShown(true); + } + + private void hookToolStripMenuItem_Click(object sender, EventArgs e){ + keyboardHook.StopHook(); + keyboardHook.StartHook(); + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e){ + Application.Exit(); + } + + private void keyboardHook_Triggered(object sender, EventArgs e){ + SetShown(!Visible); + } + + private void focusTimer_Tick(object sender, EventArgs e){ + WindowState = FormWindowState.Minimized; + Show(); + Activate(); + WindowState = FormWindowState.Normal; + + queryBox.Focus(); + focusTimer.Stop(); + } + + private void queryBox_CommandRan(object sender, CommandEventArgs e){ + try{ + string result = processor.Run(e.Command); + + if (result != null){ + queryLog.AddEntry("> "+e.Command.Text, QueryHistoryLog.EntryType.UserInput); + history.AddQuery(e.Command.Text); + + queryLog.AddEntry(result, QueryHistoryLog.EntryType.CommandResult); + history.AddResult(result); + } + }catch(CommandException ex){ + queryLog.AddEntry("> "+e.Command.Text, QueryHistoryLog.EntryType.UserInput); + history.AddQuery(e.Command.Text); + + queryLog.AddEntry(ex.Message, QueryHistoryLog.EntryType.Error); + } + } + + private bool ProcessSingleToken(string token){ + switch(token){ + case "exit": + case "quit": + Application.Exit(); + return true; + + case "clear": + queryLog.ClearEntries(); + history.Clear(); + return true; + + case "hide": + Hide(); + return true; + + default: + return false; + } + } + } +} diff --git a/Query/MainForm.resx b/Query/MainForm.resx new file mode 100644 index 0000000..a73ff59 --- /dev/null +++ b/Query/MainForm.resx @@ -0,0 +1,219 @@ +<?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> + <metadata name="trayIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> + <value>17, 17</value> + </metadata> + <metadata name="contextMenuTray.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> + <value>112, 17</value> + </metadata> + <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> + <data name="trayIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + AAABAAEAGBgAAAEAIACICQAAFgAAACgAAAAYAAAAMAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAkJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9AQED/QEBA////////////QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA//// + ////////QEBA////////////QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA//// + /////////////0BAQP9AQED/QEBA/0BAQP9AQED/QEBA////////////QEBA////////////QEBA/0BA + QP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP////////////////9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9AQED/QEBA/0BAQP9AQED/////////////////QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA//// + /////////////0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP////////////////9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/////////////////QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED///////// + ////////QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP////////////////9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA//// + /////////////0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/////////////////QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BA + QP////////////////9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/////////////////0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9AQED/QEBA////////////QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8AAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA + AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA + AEE= +</value> + </data> + <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + AAABAAEAGBgAAAEAIACICQAAFgAAACgAAAAYAAAAMAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAkJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9AQED/QEBA////////////QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA//// + ////////QEBA////////////QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA//// + /////////////0BAQP9AQED/QEBA/0BAQP9AQED/QEBA////////////QEBA////////////QEBA/0BA + QP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP////////////////9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9AQED/QEBA/0BAQP9AQED/////////////////QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA//// + /////////////0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP////////////////9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/////////////////QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED///////// + ////////QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP////////////////9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA//// + /////////////0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/////////////////QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BA + QP////////////////9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/////////////////0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9AQED/QEBA////////////QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BA + QP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8AAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA + AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA + AEE= +</value> + </data> +</root> \ No newline at end of file diff --git a/Query/Program.cs b/Query/Program.cs new file mode 100644 index 0000000..4f388cb --- /dev/null +++ b/Query/Program.cs @@ -0,0 +1,13 @@ +using System; +using System.Windows.Forms; + +namespace Query{ + static class Program{ + [STAThread] + private static void Main(){ + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} diff --git a/Query/Properties/AssemblyInfo.cs b/Query/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e87d336 --- /dev/null +++ b/Query/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Query")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Query")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4523d47a-d88d-49d9-b4db-b4ae213cd2b8")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Query/Properties/Resources.Designer.cs b/Query/Properties/Resources.Designer.cs new file mode 100644 index 0000000..01793dd --- /dev/null +++ b/Query/Properties/Resources.Designer.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// <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 Query.Properties { + + + /// <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", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal 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)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if ((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Query.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)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Query/Properties/Resources.resx b/Query/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Query/Properties/Resources.resx @@ -0,0 +1,117 @@ +<?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.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: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" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + </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" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + </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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root> \ No newline at end of file diff --git a/Query/Properties/Settings.Designer.cs b/Query/Properties/Settings.Designer.cs new file mode 100644 index 0000000..1d10fe5 --- /dev/null +++ b/Query/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// <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 Query.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Query/Properties/Settings.settings b/Query/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Query/Properties/Settings.settings @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8'?> +<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"> + <Profiles> + <Profile Name="(Default)" /> + </Profiles> + <Settings /> +</SettingsFile> diff --git a/Query/Query.csproj b/Query/Query.csproj new file mode 100644 index 0000000..3fbc3f3 --- /dev/null +++ b/Query/Query.csproj @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{1A2176AF-3885-4619-8F85-4C751A5ABA8F}</ProjectGuid> + <OutputType>WinExe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Query</RootNamespace> + <AssemblyName>Query</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugType>none</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Windows.Forms" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Controls\QueryHistoryLog.cs"> + <SubType>UserControl</SubType> + </Compile> + <Compile Include="Controls\QueryHistoryLog.Designer.cs"> + <DependentUpon>QueryHistoryLog.cs</DependentUpon> + </Compile> + <Compile Include="Controls\QueryTextBox.cs"> + <SubType>UserControl</SubType> + </Compile> + <Compile Include="Controls\QueryTextBox.Designer.cs"> + <DependentUpon>QueryTextBox.cs</DependentUpon> + </Compile> + <Compile Include="Core\CommandHistory.cs" /> + <Compile Include="Core\CommandProcessor.cs" /> + <Compile Include="MainForm.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="MainForm.Designer.cs"> + <DependentUpon>MainForm.cs</DependentUpon> + </Compile> + <Compile Include="Core\KeyboardHook.cs" /> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <EmbeddedResource Include="MainForm.resx"> + <DependentUpon>MainForm.cs</DependentUpon> + </EmbeddedResource> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + <SubType>Designer</SubType> + </EmbeddedResource> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + <Compile Include="Properties\Settings.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Settings.settings</DependentUpon> + <DesignTimeSharedInput>True</DesignTimeSharedInput> + </Compile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\AppCalc\AppCalc.csproj"> + <Project>{c7a21640-caf3-40e8-aa6a-793181bd28aa}</Project> + <Name>AppCalc</Name> + </ProjectReference> + <ProjectReference Include="..\AppConv\AppConv.csproj"> + <Project>{1ac5280a-81d1-4e02-9122-db358734ffb4}</Project> + <Name>AppConv</Name> + </ProjectReference> + <ProjectReference Include="..\AppMeme\AppMeme.csproj"> + <Project>{4e27adc4-fcbe-451e-a1f9-8050da22a6e1}</Project> + <Name>AppMeme</Name> + </ProjectReference> + <ProjectReference Include="..\AppWindows\AppSys.csproj"> + <Project>{e71afa58-a144-4170-af7b-05730c04cf59}</Project> + <Name>AppSys</Name> + </ProjectReference> + <ProjectReference Include="..\Base\Base.csproj"> + <Project>{66cf4f71-50dd-4c65-ab96-35d1193ffb50}</Project> + <Name>Base</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..bb78ae6944425c2a28ae41cf057531b1e5571142 GIT binary patch literal 2462 zcmeH}F$#b%3`M`A7Z68>4vrq7-p*Us1QY@io5TtZM!uAgydUGBKu6a&g6<Qx9vA@3 zBuZf+abAm*Qu$@uLC(3fkhbp@Y-ZH><%l~!StHLLKKE%Jk}1y?KG(?5JhXgmKWAUm z!^)37hld~W@bbMLU*mh<vuA!Un|EpDN7z<=lx^WZVSD&o8<BPY5w>OiDEI8s=Ku58 L?>zk%t#4`v?6?kK literal 0 HcmV?d00001