mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge "dev" into "improve-calculator"
This commit is contained in:
commit
ec2aaa8457
98 changed files with 2216 additions and 1216 deletions
|
|
@ -37,32 +37,13 @@
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Data.SQLite, Version=1.0.111.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\System.Data.SQLite.Core.1.0.111.0\lib\net451\System.Data.SQLite.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Data.SQLite.EF6, Version=1.0.111.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\System.Data.SQLite.EF6.1.0.111.0\lib\net451\System.Data.SQLite.EF6.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Data.SQLite.Linq, Version=1.0.111.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\System.Data.SQLite.Linq.1.0.111.0\lib\net451\System.Data.SQLite.Linq.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Xaml" />
|
<Reference Include="System.Xaml" />
|
||||||
<Reference Include="UnidecodeSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\UnidecodeSharp.1.0.0.0\lib\net35\UnidecodeSharp.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -79,7 +60,6 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="app.config" />
|
<None Include="app.config" />
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -123,16 +103,19 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.Data.SQLite">
|
||||||
|
<Version>1.0.111</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Data.SQLite.Core">
|
||||||
|
<Version>1.0.111</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="UnidecodeSharp">
|
||||||
|
<Version>1.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||||
<Import Project="..\..\packages\System.Data.SQLite.Core.1.0.111.0\build\net451\System.Data.SQLite.Core.targets" Condition="Exists('..\..\packages\System.Data.SQLite.Core.1.0.111.0\build\net451\System.Data.SQLite.Core.targets')" />
|
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Error Condition="!Exists('..\..\packages\System.Data.SQLite.Core.1.0.111.0\build\net451\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\System.Data.SQLite.Core.1.0.111.0\build\net451\System.Data.SQLite.Core.targets'))" />
|
|
||||||
</Target>
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<configSections>
|
<configSections>
|
||||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
|
|
||||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||||
</configSections>
|
</configSections>
|
||||||
<startup>
|
<startup>
|
||||||
|
|
@ -18,10 +18,5 @@
|
||||||
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
|
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
|
||||||
</providers>
|
</providers>
|
||||||
</entityFramework>
|
</entityFramework>
|
||||||
<system.data>
|
|
||||||
<DbProviderFactories>
|
|
||||||
<remove invariant="System.Data.SQLite.EF6" />
|
|
||||||
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
|
|
||||||
<remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
|
|
||||||
</system.data>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="EntityFramework" version="6.2.0" targetFramework="net452" />
|
|
||||||
<package id="System.Data.SQLite" version="1.0.111.0" targetFramework="net452" />
|
|
||||||
<package id="System.Data.SQLite.Core" version="1.0.111.0" targetFramework="net452" />
|
|
||||||
<package id="System.Data.SQLite.EF6" version="1.0.111.0" targetFramework="net452" />
|
|
||||||
<package id="System.Data.SQLite.Linq" version="1.0.111.0" targetFramework="net452" />
|
|
||||||
<package id="UnidecodeSharp" version="1.0.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -64,7 +64,6 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -130,6 +129,17 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Mages">
|
||||||
|
<Version>1.5.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Include="Views\CalculatorSettings.xaml">
|
<Page Include="Views\CalculatorSettings.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Mages" version="1.5.0" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -55,7 +55,6 @@
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -112,6 +111,14 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -27,7 +27,6 @@ namespace Wox.Plugin.ControlPanel
|
||||||
Directory.CreateDirectory(iconFolder);
|
Directory.CreateDirectory(iconFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
foreach (ControlPanelItem item in controlPanelItems)
|
foreach (ControlPanelItem item in controlPanelItems)
|
||||||
{
|
{
|
||||||
if (!File.Exists(iconFolder + item.GUID + fileType) && item.Icon != null)
|
if (!File.Exists(iconFolder + item.GUID + fileType) && item.Icon != null)
|
||||||
|
|
@ -43,7 +42,10 @@ namespace Wox.Plugin.ControlPanel
|
||||||
|
|
||||||
foreach (var item in controlPanelItems)
|
foreach (var item in controlPanelItems)
|
||||||
{
|
{
|
||||||
item.Score = Score(item, query.Search);
|
var titleMatch = StringMatcher.FuzzySearch(query.Search, item.LocalizedString);
|
||||||
|
var subTitleMatch = StringMatcher.FuzzySearch(query.Search, item.InfoTip);
|
||||||
|
|
||||||
|
item.Score = Math.Max(titleMatch.Score, subTitleMatch.Score);
|
||||||
if (item.Score > 0)
|
if (item.Score > 0)
|
||||||
{
|
{
|
||||||
var result = new Result
|
var result = new Result
|
||||||
|
|
@ -66,6 +68,16 @@ namespace Wox.Plugin.ControlPanel
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (item.Score == titleMatch.Score)
|
||||||
|
{
|
||||||
|
result.TitleHighlightData = titleMatch.MatchData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.SubTitleHighlightData = subTitleMatch.MatchData;
|
||||||
|
}
|
||||||
|
|
||||||
results.Add(result);
|
results.Add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -74,26 +86,6 @@ namespace Wox.Plugin.ControlPanel
|
||||||
return panelItems;
|
return panelItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int Score(ControlPanelItem item, string query)
|
|
||||||
{
|
|
||||||
var scores = new List<int> {0};
|
|
||||||
if (!string.IsNullOrEmpty(item.LocalizedString))
|
|
||||||
{
|
|
||||||
var score1 = StringMatcher.FuzzySearch(query, item.LocalizedString).ScoreAfterSearchPrecisionFilter();
|
|
||||||
var score2 = StringMatcher.ScoreForPinyin(item.LocalizedString, query);
|
|
||||||
scores.Add(score1);
|
|
||||||
scores.Add(score2);
|
|
||||||
}
|
|
||||||
if (!string.IsNullOrEmpty(item.InfoTip))
|
|
||||||
{
|
|
||||||
var score1 = StringMatcher.FuzzySearch(query, item.InfoTip).ScoreAfterSearchPrecisionFilter();
|
|
||||||
var score2 = StringMatcher.ScoreForPinyin(item.InfoTip, query);
|
|
||||||
scores.Add(score1);
|
|
||||||
scores.Add(score2);
|
|
||||||
}
|
|
||||||
return scores.Max();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetTranslatedPluginTitle()
|
public string GetTranslatedPluginTitle()
|
||||||
{
|
{
|
||||||
return context.API.GetTranslation("wox_plugin_controlpanel_plugin_name");
|
return context.API.GetTranslation("wox_plugin_controlpanel_plugin_name");
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -114,6 +113,14 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -2,76 +2,36 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using Wox.Infrastructure.Logger;
|
||||||
using Wox.Plugin.Everything.Everything.Exceptions;
|
using Wox.Plugin.Everything.Everything.Exceptions;
|
||||||
|
|
||||||
namespace Wox.Plugin.Everything.Everything
|
namespace Wox.Plugin.Everything.Everything
|
||||||
{
|
{
|
||||||
public sealed class EverythingAPI
|
public interface IEverythingApi
|
||||||
{
|
{
|
||||||
#region DllImport
|
/// <summary>
|
||||||
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
|
/// Searches the specified key word.
|
||||||
private static extern int Everything_SetSearchW(string lpSearchString);
|
/// </summary>
|
||||||
[DllImport(Main.DLL)]
|
/// <param name="keyWord">The key word.</param>
|
||||||
private static extern void Everything_SetMatchPath(bool bEnable);
|
/// <param name="token">token that allow cancellation</param>
|
||||||
[DllImport(Main.DLL)]
|
/// <param name="offset">The offset.</param>
|
||||||
private static extern void Everything_SetMatchCase(bool bEnable);
|
/// <param name="maxCount">The max count.</param>
|
||||||
[DllImport(Main.DLL)]
|
/// <returns></returns>
|
||||||
private static extern void Everything_SetMatchWholeWord(bool bEnable);
|
List<SearchResult> Search(string keyWord, CancellationToken token, int offset = 0, int maxCount = 100);
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern void Everything_SetRegex(bool bEnable);
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern void Everything_SetMax(int dwMax);
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern void Everything_SetOffset(int dwOffset);
|
|
||||||
|
|
||||||
[DllImport(Main.DLL)]
|
void Load(string sdkPath);
|
||||||
private static extern bool Everything_GetMatchPath();
|
}
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern bool Everything_GetMatchCase();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern bool Everything_GetMatchWholeWord();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern bool Everything_GetRegex();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern UInt32 Everything_GetMax();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern UInt32 Everything_GetOffset();
|
|
||||||
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
|
|
||||||
private static extern string Everything_GetSearchW();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern StateCode Everything_GetLastError();
|
|
||||||
|
|
||||||
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
|
public sealed class EverythingApi : IEverythingApi
|
||||||
private static extern bool Everything_QueryW(bool bWait);
|
{
|
||||||
|
private const int BufferSize = 4096;
|
||||||
|
|
||||||
[DllImport(Main.DLL)]
|
private readonly object _syncObject = new object();
|
||||||
private static extern void Everything_SortResultsByPath();
|
// cached buffer to remove redundant allocations.
|
||||||
|
private readonly StringBuilder _buffer = new StringBuilder(BufferSize);
|
||||||
|
|
||||||
[DllImport(Main.DLL)]
|
public enum StateCode
|
||||||
private static extern int Everything_GetNumFileResults();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern int Everything_GetNumFolderResults();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern int Everything_GetNumResults();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern int Everything_GetTotFileResults();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern int Everything_GetTotFolderResults();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern int Everything_GetTotResults();
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern bool Everything_IsVolumeResult(int nIndex);
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern bool Everything_IsFolderResult(int nIndex);
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern bool Everything_IsFileResult(int nIndex);
|
|
||||||
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
|
|
||||||
private static extern void Everything_GetResultFullPathNameW(int nIndex, StringBuilder lpString, int nMaxCount);
|
|
||||||
[DllImport(Main.DLL)]
|
|
||||||
private static extern void Everything_Reset();
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
enum StateCode
|
|
||||||
{
|
{
|
||||||
OK,
|
OK,
|
||||||
MemoryError,
|
MemoryError,
|
||||||
|
|
@ -87,15 +47,15 @@ namespace Wox.Plugin.Everything.Everything
|
||||||
/// Gets or sets a value indicating whether [match path].
|
/// Gets or sets a value indicating whether [match path].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value><c>true</c> if [match path]; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if [match path]; otherwise, <c>false</c>.</value>
|
||||||
public Boolean MatchPath
|
public bool MatchPath
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Everything_GetMatchPath();
|
return EverythingApiDllImport.Everything_GetMatchPath();
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Everything_SetMatchPath(value);
|
EverythingApiDllImport.Everything_SetMatchPath(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,15 +63,15 @@ namespace Wox.Plugin.Everything.Everything
|
||||||
/// Gets or sets a value indicating whether [match case].
|
/// Gets or sets a value indicating whether [match case].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value><c>true</c> if [match case]; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if [match case]; otherwise, <c>false</c>.</value>
|
||||||
public Boolean MatchCase
|
public bool MatchCase
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Everything_GetMatchCase();
|
return EverythingApiDllImport.Everything_GetMatchCase();
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Everything_SetMatchCase(value);
|
EverythingApiDllImport.Everything_SetMatchCase(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,15 +79,15 @@ namespace Wox.Plugin.Everything.Everything
|
||||||
/// Gets or sets a value indicating whether [match whole word].
|
/// Gets or sets a value indicating whether [match whole word].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value><c>true</c> if [match whole word]; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if [match whole word]; otherwise, <c>false</c>.</value>
|
||||||
public Boolean MatchWholeWord
|
public bool MatchWholeWord
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Everything_GetMatchWholeWord();
|
return EverythingApiDllImport.Everything_GetMatchWholeWord();
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Everything_SetMatchWholeWord(value);
|
EverythingApiDllImport.Everything_SetMatchWholeWord(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,15 +95,15 @@ namespace Wox.Plugin.Everything.Everything
|
||||||
/// Gets or sets a value indicating whether [enable regex].
|
/// Gets or sets a value indicating whether [enable regex].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value><c>true</c> if [enable regex]; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if [enable regex]; otherwise, <c>false</c>.</value>
|
||||||
public Boolean EnableRegex
|
public bool EnableRegex
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Everything_GetRegex();
|
return EverythingApiDllImport.Everything_GetRegex();
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Everything_SetRegex(value);
|
EverythingApiDllImport.Everything_SetRegex(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,12 +112,91 @@ namespace Wox.Plugin.Everything.Everything
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
Everything_Reset();
|
lock (_syncObject)
|
||||||
|
{
|
||||||
|
EverythingApiDllImport.Everything_Reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void no()
|
/// <summary>
|
||||||
|
/// Searches the specified key word and reset the everything API afterwards
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="keyWord">The key word.</param>
|
||||||
|
/// <param name="token">when cancelled the current search will stop and exit (and would not reset)</param>
|
||||||
|
/// <param name="offset">The offset.</param>
|
||||||
|
/// <param name="maxCount">The max count.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<SearchResult> Search(string keyWord, CancellationToken token, int offset = 0, int maxCount = 100)
|
||||||
{
|
{
|
||||||
switch (Everything_GetLastError())
|
if (string.IsNullOrEmpty(keyWord))
|
||||||
|
throw new ArgumentNullException(nameof(keyWord));
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(offset));
|
||||||
|
|
||||||
|
if (maxCount < 0)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(maxCount));
|
||||||
|
|
||||||
|
lock (_syncObject)
|
||||||
|
{
|
||||||
|
if (keyWord.StartsWith("@"))
|
||||||
|
{
|
||||||
|
EverythingApiDllImport.Everything_SetRegex(true);
|
||||||
|
keyWord = keyWord.Substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
EverythingApiDllImport.Everything_SetSearchW(keyWord);
|
||||||
|
EverythingApiDllImport.Everything_SetOffset(offset);
|
||||||
|
EverythingApiDllImport.Everything_SetMax(maxCount);
|
||||||
|
|
||||||
|
if (token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!EverythingApiDllImport.Everything_QueryW(true))
|
||||||
|
{
|
||||||
|
CheckAndThrowExceptionOnError();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var results = new List<SearchResult>();
|
||||||
|
for (int idx = 0; idx < EverythingApiDllImport.Everything_GetNumResults(); ++idx)
|
||||||
|
{
|
||||||
|
if (token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
EverythingApiDllImport.Everything_GetResultFullPathNameW(idx, _buffer, BufferSize);
|
||||||
|
|
||||||
|
var result = new SearchResult { FullPath = _buffer.ToString() };
|
||||||
|
if (EverythingApiDllImport.Everything_IsFolderResult(idx))
|
||||||
|
result.Type = ResultType.Folder;
|
||||||
|
else if (EverythingApiDllImport.Everything_IsFileResult(idx))
|
||||||
|
result.Type = ResultType.File;
|
||||||
|
|
||||||
|
results.Add(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
Reset();
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
private static extern int LoadLibrary(string name);
|
||||||
|
|
||||||
|
public void Load(string sdkPath)
|
||||||
|
{
|
||||||
|
LoadLibrary(sdkPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CheckAndThrowExceptionOnError()
|
||||||
|
{
|
||||||
|
switch (EverythingApiDllImport.Everything_GetLastError())
|
||||||
{
|
{
|
||||||
case StateCode.CreateThreadError:
|
case StateCode.CreateThreadError:
|
||||||
throw new CreateThreadException();
|
throw new CreateThreadException();
|
||||||
|
|
@ -175,71 +214,5 @@ namespace Wox.Plugin.Everything.Everything
|
||||||
throw new RegisterClassExException();
|
throw new RegisterClassExException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Searches the specified key word.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="keyWord">The key word.</param>
|
|
||||||
/// <param name="offset">The offset.</param>
|
|
||||||
/// <param name="maxCount">The max count.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IEnumerable<SearchResult> Search(string keyWord, int offset = 0, int maxCount = 100)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(keyWord))
|
|
||||||
throw new ArgumentNullException("keyWord");
|
|
||||||
|
|
||||||
if (offset < 0)
|
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
|
||||||
|
|
||||||
if (maxCount < 0)
|
|
||||||
throw new ArgumentOutOfRangeException("maxCount");
|
|
||||||
|
|
||||||
if (keyWord.StartsWith("@"))
|
|
||||||
{
|
|
||||||
Everything_SetRegex(true);
|
|
||||||
keyWord = keyWord.Substring(1);
|
|
||||||
}
|
|
||||||
Everything_SetSearchW(keyWord);
|
|
||||||
Everything_SetOffset(offset);
|
|
||||||
Everything_SetMax(maxCount);
|
|
||||||
|
|
||||||
|
|
||||||
if (!Everything_QueryW(true))
|
|
||||||
{
|
|
||||||
switch (Everything_GetLastError())
|
|
||||||
{
|
|
||||||
case StateCode.CreateThreadError:
|
|
||||||
throw new CreateThreadException();
|
|
||||||
case StateCode.CreateWindowError:
|
|
||||||
throw new CreateWindowException();
|
|
||||||
case StateCode.InvalidCallError:
|
|
||||||
throw new InvalidCallException();
|
|
||||||
case StateCode.InvalidIndexError:
|
|
||||||
throw new InvalidIndexException();
|
|
||||||
case StateCode.IPCError:
|
|
||||||
throw new IPCErrorException();
|
|
||||||
case StateCode.MemoryError:
|
|
||||||
throw new MemoryErrorException();
|
|
||||||
case StateCode.RegisterClassExError:
|
|
||||||
throw new RegisterClassExException();
|
|
||||||
}
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int bufferSize = 4096;
|
|
||||||
StringBuilder buffer = new StringBuilder(bufferSize);
|
|
||||||
for (int idx = 0; idx < Everything_GetNumResults(); ++idx)
|
|
||||||
{
|
|
||||||
Everything_GetResultFullPathNameW(idx, buffer, bufferSize);
|
|
||||||
|
|
||||||
var result = new SearchResult { FullPath = buffer.ToString() };
|
|
||||||
if (Everything_IsFolderResult(idx))
|
|
||||||
result.Type = ResultType.Folder;
|
|
||||||
else if (Everything_IsFileResult(idx))
|
|
||||||
result.Type = ResultType.File;
|
|
||||||
|
|
||||||
yield return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Wox.Plugin.Everything.Everything
|
||||||
|
{
|
||||||
|
public sealed class EverythingApiDllImport
|
||||||
|
{
|
||||||
|
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern int Everything_SetSearchW(string lpSearchString);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern void Everything_SetMatchPath(bool bEnable);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern void Everything_SetMatchCase(bool bEnable);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern void Everything_SetMatchWholeWord(bool bEnable);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern void Everything_SetRegex(bool bEnable);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern void Everything_SetMax(int dwMax);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern void Everything_SetOffset(int dwOffset);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern bool Everything_GetMatchPath();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern bool Everything_GetMatchCase();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern bool Everything_GetMatchWholeWord();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern bool Everything_GetRegex();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern uint Everything_GetMax();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern uint Everything_GetOffset();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern string Everything_GetSearchW();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern EverythingApi.StateCode Everything_GetLastError();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern bool Everything_QueryW(bool bWait);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern void Everything_SortResultsByPath();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern int Everything_GetNumFileResults();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern int Everything_GetNumFolderResults();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern int Everything_GetNumResults();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern int Everything_GetTotFileResults();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern int Everything_GetTotFolderResults();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern int Everything_GetTotResults();
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern bool Everything_IsVolumeResult(int nIndex);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern bool Everything_IsFolderResult(int nIndex);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern bool Everything_IsFileResult(int nIndex);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern void Everything_GetResultFullPathNameW(int nIndex, StringBuilder lpString, int nMaxCount);
|
||||||
|
|
||||||
|
[DllImport(Main.DLL)]
|
||||||
|
internal static extern void Everything_Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,11 +3,12 @@ using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using Wox.Infrastructure;
|
using Wox.Infrastructure;
|
||||||
|
using Wox.Infrastructure.Logger;
|
||||||
using Wox.Infrastructure.Storage;
|
using Wox.Infrastructure.Storage;
|
||||||
using Wox.Plugin.Everything.Everything;
|
using Wox.Plugin.Everything.Everything;
|
||||||
|
|
||||||
|
|
@ -15,14 +16,16 @@ namespace Wox.Plugin.Everything
|
||||||
{
|
{
|
||||||
public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu, ISavable
|
public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu, ISavable
|
||||||
{
|
{
|
||||||
private readonly EverythingAPI _api = new EverythingAPI();
|
|
||||||
|
|
||||||
public const string DLL = "Everything.dll";
|
public const string DLL = "Everything.dll";
|
||||||
|
private readonly IEverythingApi _api = new EverythingApi();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private PluginInitContext _context;
|
private PluginInitContext _context;
|
||||||
|
|
||||||
private Settings _settings;
|
private Settings _settings;
|
||||||
private PluginJsonStorage<Settings> _storage;
|
private PluginJsonStorage<Settings> _storage;
|
||||||
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
|
|
@ -31,53 +34,24 @@ namespace Wox.Plugin.Everything
|
||||||
|
|
||||||
public List<Result> Query(Query query)
|
public List<Result> Query(Query query)
|
||||||
{
|
{
|
||||||
|
_cancellationTokenSource?.Cancel(); // cancel if already exist
|
||||||
|
var cts = _cancellationTokenSource = new CancellationTokenSource();
|
||||||
var results = new List<Result>();
|
var results = new List<Result>();
|
||||||
if (!string.IsNullOrEmpty(query.Search))
|
if (!string.IsNullOrEmpty(query.Search))
|
||||||
{
|
{
|
||||||
var keyword = query.Search;
|
var keyword = query.Search;
|
||||||
if (_settings.MaxSearchCount <= 0)
|
|
||||||
{
|
|
||||||
_settings.MaxSearchCount = 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var searchList = _api.Search(keyword, maxCount: _settings.MaxSearchCount).ToList();
|
var searchList = _api.Search(keyword, cts.Token, maxCount: _settings.MaxSearchCount);
|
||||||
foreach (var s in searchList)
|
if (searchList == null)
|
||||||
{
|
{
|
||||||
var path = s.FullPath;
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
string workingDir = null;
|
foreach (var searchResult in searchList)
|
||||||
if (_settings.UseLocationAsWorkingDir)
|
{
|
||||||
workingDir = Path.GetDirectoryName(path);
|
var r = CreateResult(keyword, searchResult);
|
||||||
|
|
||||||
Result r = new Result();
|
|
||||||
r.Title = Path.GetFileName(path);
|
|
||||||
r.SubTitle = path;
|
|
||||||
r.IcoPath = path;
|
|
||||||
r.Action = c =>
|
|
||||||
{
|
|
||||||
bool hide;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Process.Start(new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = path,
|
|
||||||
UseShellExecute = true,
|
|
||||||
WorkingDirectory = workingDir
|
|
||||||
});
|
|
||||||
hide = true;
|
|
||||||
}
|
|
||||||
catch (Win32Exception)
|
|
||||||
{
|
|
||||||
var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
|
|
||||||
var message = "Can't open this file";
|
|
||||||
_context.API.ShowMsg(name, message, string.Empty);
|
|
||||||
hide = false;
|
|
||||||
}
|
|
||||||
return hide;
|
|
||||||
};
|
|
||||||
r.ContextData = s;
|
|
||||||
results.Add(r);
|
results.Add(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,6 +65,7 @@ namespace Wox.Plugin.Everything
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
Log.Exception("EverythingPlugin", "Query Error", e);
|
||||||
results.Add(new Result
|
results.Add(new Result
|
||||||
{
|
{
|
||||||
Title = _context.API.GetTranslation("wox_plugin_everything_query_error"),
|
Title = _context.API.GetTranslation("wox_plugin_everything_query_error"),
|
||||||
|
|
@ -106,13 +81,51 @@ namespace Wox.Plugin.Everything
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_api.Reset();
|
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("kernel32.dll")]
|
private Result CreateResult(string keyword, SearchResult searchResult)
|
||||||
private static extern int LoadLibrary(string name);
|
{
|
||||||
|
var path = searchResult.FullPath;
|
||||||
|
|
||||||
|
string workingDir = null;
|
||||||
|
if (_settings.UseLocationAsWorkingDir)
|
||||||
|
workingDir = Path.GetDirectoryName(path);
|
||||||
|
|
||||||
|
var r = new Result
|
||||||
|
{
|
||||||
|
Title = Path.GetFileName(path),
|
||||||
|
SubTitle = path,
|
||||||
|
IcoPath = path,
|
||||||
|
TitleHighlightData = StringMatcher.FuzzySearch(keyword, Path.GetFileName(path)).MatchData,
|
||||||
|
Action = c =>
|
||||||
|
{
|
||||||
|
bool hide;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.Start(new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = path, UseShellExecute = true, WorkingDirectory = workingDir
|
||||||
|
});
|
||||||
|
hide = true;
|
||||||
|
}
|
||||||
|
catch (Win32Exception)
|
||||||
|
{
|
||||||
|
var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
|
||||||
|
var message = "Can't open this file";
|
||||||
|
_context.API.ShowMsg(name, message, string.Empty);
|
||||||
|
hide = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hide;
|
||||||
|
},
|
||||||
|
ContextData = searchResult,
|
||||||
|
SubTitleHighlightData = StringMatcher.FuzzySearch(keyword, path).MatchData
|
||||||
|
};
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private List<ContextMenu> GetDefaultContextMenu()
|
private List<ContextMenu> GetDefaultContextMenu()
|
||||||
{
|
{
|
||||||
|
|
@ -147,6 +160,10 @@ namespace Wox.Plugin.Everything
|
||||||
_context = context;
|
_context = context;
|
||||||
_storage = new PluginJsonStorage<Settings>();
|
_storage = new PluginJsonStorage<Settings>();
|
||||||
_settings = _storage.Load();
|
_settings = _storage.Load();
|
||||||
|
if (_settings.MaxSearchCount <= 0)
|
||||||
|
{
|
||||||
|
_settings.MaxSearchCount = Settings.DefaultMaxSearchCount;
|
||||||
|
}
|
||||||
|
|
||||||
var pluginDirectory = context.CurrentPluginMetadata.PluginDirectory;
|
var pluginDirectory = context.CurrentPluginMetadata.PluginDirectory;
|
||||||
const string sdk = "EverythingSDK";
|
const string sdk = "EverythingSDK";
|
||||||
|
|
@ -156,7 +173,7 @@ namespace Wox.Plugin.Everything
|
||||||
|
|
||||||
var sdkPath = Path.Combine(sdkDirectory, DLL);
|
var sdkPath = Path.Combine(sdkDirectory, DLL);
|
||||||
Constant.EverythingSDKPath = sdkPath;
|
Constant.EverythingSDKPath = sdkPath;
|
||||||
LoadLibrary(sdkPath);
|
_api.Load(sdkPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CpuType()
|
private static string CpuType()
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,13 @@ namespace Wox.Plugin.Everything
|
||||||
{
|
{
|
||||||
public class Settings
|
public class Settings
|
||||||
{
|
{
|
||||||
|
public const int DefaultMaxSearchCount = 50;
|
||||||
|
|
||||||
public string EditorPath { get; set; } = "";
|
public string EditorPath { get; set; } = "";
|
||||||
|
|
||||||
public List<ContextMenu> ContextMenus = new List<ContextMenu>();
|
public List<ContextMenu> ContextMenus = new List<ContextMenu>();
|
||||||
|
|
||||||
public int MaxSearchCount { get; set; } = 100;
|
public int MaxSearchCount { get; set; } = DefaultMaxSearchCount;
|
||||||
|
|
||||||
public bool UseLocationAsWorkingDir { get; set; } = false;
|
public bool UseLocationAsWorkingDir { get; set; } = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@
|
||||||
<Compile Include="EverythingSettings.xaml.cs">
|
<Compile Include="EverythingSettings.xaml.cs">
|
||||||
<DependentUpon>EverythingSettings.xaml</DependentUpon>
|
<DependentUpon>EverythingSettings.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Everything\EverythingApiDllImport.cs" />
|
||||||
<Compile Include="Everything\Exceptions\CreateThreadException.cs" />
|
<Compile Include="Everything\Exceptions\CreateThreadException.cs" />
|
||||||
<Compile Include="Everything\Exceptions\CreateWindowException.cs" />
|
<Compile Include="Everything\Exceptions\CreateWindowException.cs" />
|
||||||
<Compile Include="Everything\EverythingAPI.cs" />
|
<Compile Include="Everything\EverythingAPI.cs" />
|
||||||
|
|
@ -100,7 +101,6 @@
|
||||||
<Content Include="Images\warning.png">
|
<Content Include="Images\warning.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
|
|
@ -163,6 +163,17 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>9.0.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
218
Plugins/Wox.Plugin.Folder/ContextMenuLoader.cs
Normal file
218
Plugins/Wox.Plugin.Folder/ContextMenuLoader.cs
Normal file
|
|
@ -0,0 +1,218 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using Wox.Infrastructure.Logger;
|
||||||
|
using Wox.Infrastructure.Image;
|
||||||
|
using Wox.Plugin.SharedCommands;
|
||||||
|
|
||||||
|
namespace Wox.Plugin.Folder
|
||||||
|
{
|
||||||
|
internal class ContextMenuLoader : IContextMenu
|
||||||
|
{
|
||||||
|
private readonly PluginInitContext _context;
|
||||||
|
|
||||||
|
public ContextMenuLoader(PluginInitContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Result> LoadContextMenus(Result selectedResult)
|
||||||
|
{
|
||||||
|
var contextMenus = new List<Result>();
|
||||||
|
if (selectedResult.ContextData is SearchResult record)
|
||||||
|
{
|
||||||
|
if (record.Type == ResultType.File)
|
||||||
|
{
|
||||||
|
contextMenus.Add(CreateOpenWithEditorResult(record));
|
||||||
|
contextMenus.Add(CreateOpenContainingFolderResult(record));
|
||||||
|
}
|
||||||
|
|
||||||
|
var icoPath = (record.Type == ResultType.File) ? Main.FileImagePath : Main.FolderImagePath;
|
||||||
|
var fileOrFolder = (record.Type == ResultType.File) ? "file" : "folder";
|
||||||
|
contextMenus.Add(new Result
|
||||||
|
{
|
||||||
|
Title = "Copy path",
|
||||||
|
SubTitle = $"Copy the current {fileOrFolder} path to clipboard",
|
||||||
|
Action = (context) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Clipboard.SetText(record.FullPath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
var message = "Fail to set text in clipboard";
|
||||||
|
LogException(message, e);
|
||||||
|
_context.API.ShowMsg(message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
IcoPath = Main.CopyImagePath
|
||||||
|
});
|
||||||
|
|
||||||
|
contextMenus.Add(new Result
|
||||||
|
{
|
||||||
|
Title = $"Copy {fileOrFolder}",
|
||||||
|
SubTitle = $"Copy the {fileOrFolder} to clipboard",
|
||||||
|
Action = (context) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Clipboard.SetFileDropList(new System.Collections.Specialized.StringCollection { record.FullPath });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
var message = $"Fail to set {fileOrFolder} in clipboard";
|
||||||
|
LogException(message, e);
|
||||||
|
_context.API.ShowMsg(message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
IcoPath = icoPath
|
||||||
|
});
|
||||||
|
|
||||||
|
if (record.Type == ResultType.File || record.Type == ResultType.Folder)
|
||||||
|
contextMenus.Add(new Result
|
||||||
|
{
|
||||||
|
Title = $"Delete {fileOrFolder}",
|
||||||
|
SubTitle = $"Delete the selected {fileOrFolder}",
|
||||||
|
Action = (context) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (record.Type == ResultType.File)
|
||||||
|
File.Delete(record.FullPath);
|
||||||
|
else
|
||||||
|
Directory.Delete(record.FullPath);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
var message = $"Fail to delete {fileOrFolder} at {record.FullPath}";
|
||||||
|
LogException(message, e);
|
||||||
|
_context.API.ShowMsg(message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
IcoPath = Main.DeleteFileFolderImagePath
|
||||||
|
});
|
||||||
|
|
||||||
|
if (record.Type == ResultType.File && CanRunAsDifferentUser(record.FullPath))
|
||||||
|
contextMenus.Add(new Result
|
||||||
|
{
|
||||||
|
Title = "Run as different user",
|
||||||
|
Action = (context) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Task.Run(()=> ShellCommand.RunAsDifferentUser(record.FullPath.SetProcessStartInfo()));
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e)
|
||||||
|
{
|
||||||
|
var name = "Plugin: Folder";
|
||||||
|
var message = $"File not found: {e.Message}";
|
||||||
|
_context.API.ShowMsg(name, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
IcoPath = "Images/user.png"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return contextMenus;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result CreateOpenContainingFolderResult(SearchResult record)
|
||||||
|
{
|
||||||
|
return new Result
|
||||||
|
{
|
||||||
|
Title = "Open containing folder",
|
||||||
|
Action = _ =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.Start("explorer.exe", $" /select,\"{record.FullPath}\"");
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
var message = $"Fail to open file at {record.FullPath}";
|
||||||
|
LogException(message, e);
|
||||||
|
_context.API.ShowMsg(message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
IcoPath = Main.FolderImagePath
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Result CreateOpenWithEditorResult(SearchResult record)
|
||||||
|
{
|
||||||
|
string editorPath = "notepad.exe"; // TODO add the ability to create a custom editor
|
||||||
|
|
||||||
|
var name = "Open With Editor: " + Path.GetFileNameWithoutExtension(editorPath);
|
||||||
|
return new Result
|
||||||
|
{
|
||||||
|
Title = name,
|
||||||
|
Action = _ =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.Start(editorPath, record.FullPath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
var message = $"Fail to editor for file at {record.FullPath}";
|
||||||
|
LogException(message, e);
|
||||||
|
_context.API.ShowMsg(message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
IcoPath = editorPath
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogException(string message, Exception e)
|
||||||
|
{
|
||||||
|
Log.Exception($"|Wox.Plugin.Folder.ContextMenu|{message}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanRunAsDifferentUser(string path)
|
||||||
|
{
|
||||||
|
switch(Path.GetExtension(path))
|
||||||
|
{
|
||||||
|
case ".exe":
|
||||||
|
case ".bat":
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SearchResult
|
||||||
|
{
|
||||||
|
public string FullPath { get; set; }
|
||||||
|
public ResultType Type { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ResultType
|
||||||
|
{
|
||||||
|
Volume,
|
||||||
|
Folder,
|
||||||
|
File
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Plugins/Wox.Plugin.Folder/Images/deletefilefolder.png
Normal file
BIN
Plugins/Wox.Plugin.Folder/Images/deletefilefolder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
BIN
Plugins/Wox.Plugin.Folder/Images/file.png
Normal file
BIN
Plugins/Wox.Plugin.Folder/Images/file.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 290 B |
BIN
Plugins/Wox.Plugin.Folder/Images/user.png
Normal file
BIN
Plugins/Wox.Plugin.Folder/Images/user.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
|
|
@ -5,17 +5,26 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using Wox.Infrastructure;
|
||||||
using Wox.Infrastructure.Storage;
|
using Wox.Infrastructure.Storage;
|
||||||
|
|
||||||
namespace Wox.Plugin.Folder
|
namespace Wox.Plugin.Folder
|
||||||
{
|
{
|
||||||
public class Main : IPlugin, ISettingProvider, IPluginI18n, ISavable
|
public class Main : IPlugin, ISettingProvider, IPluginI18n, ISavable, IContextMenu
|
||||||
{
|
{
|
||||||
|
public const string FolderImagePath = "Images\\folder.png";
|
||||||
|
public const string FileImagePath = "Images\\file.png";
|
||||||
|
public const string DeleteFileFolderImagePath = "Images\\deletefilefolder.png";
|
||||||
|
public const string CopyImagePath = "Images\\copy.png";
|
||||||
|
|
||||||
|
private string DefaultFolderSubtitleString = "Ctrl + Enter to open the directory";
|
||||||
|
|
||||||
private static List<string> _driverNames;
|
private static List<string> _driverNames;
|
||||||
private PluginInitContext _context;
|
private PluginInitContext _context;
|
||||||
|
|
||||||
private readonly Settings _settings;
|
private readonly Settings _settings;
|
||||||
private readonly PluginJsonStorage<Settings> _storage;
|
private readonly PluginJsonStorage<Settings> _storage;
|
||||||
|
private IContextMenu _contextMenuLoader;
|
||||||
|
|
||||||
public Main()
|
public Main()
|
||||||
{
|
{
|
||||||
|
|
@ -36,6 +45,7 @@ namespace Wox.Plugin.Folder
|
||||||
public void Init(PluginInitContext context)
|
public void Init(PluginInitContext context)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
|
_contextMenuLoader = new ContextMenuLoader(context);
|
||||||
InitialDriverList();
|
InitialDriverList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,7 +54,7 @@ namespace Wox.Plugin.Folder
|
||||||
var results = GetUserFolderResults(query);
|
var results = GetUserFolderResults(query);
|
||||||
|
|
||||||
string search = query.Search.ToLower();
|
string search = query.Search.ToLower();
|
||||||
if (_driverNames != null && !_driverNames.Any(search.StartsWith))
|
if (!IsDriveOrSharedFolder(search))
|
||||||
return results;
|
return results;
|
||||||
|
|
||||||
results.AddRange(QueryInternal_Directory_Exists(query));
|
results.AddRange(QueryInternal_Directory_Exists(query));
|
||||||
|
|
@ -58,13 +68,34 @@ namespace Wox.Plugin.Folder
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result CreateFolderResult(string title, string path, string queryActionKeyword)
|
private static bool IsDriveOrSharedFolder(string search)
|
||||||
|
{
|
||||||
|
if (search.StartsWith(@"\\"))
|
||||||
|
{ // share folder
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_driverNames != null && _driverNames.Any(search.StartsWith))
|
||||||
|
{ // normal drive letter
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_driverNames == null && search.Length > 2 && char.IsLetter(search[0]) && search[1] == ':')
|
||||||
|
{ // when we don't have the drive letters we can try...
|
||||||
|
return true; // we don't know so let's give it the possibility
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result CreateFolderResult(string title, string subtitle, string path, Query query)
|
||||||
{
|
{
|
||||||
return new Result
|
return new Result
|
||||||
{
|
{
|
||||||
Title = title,
|
Title = title,
|
||||||
IcoPath = path,
|
IcoPath = path,
|
||||||
SubTitle = "Ctrl + Enter to open the directory",
|
SubTitle = subtitle,
|
||||||
|
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
if (c.SpecialKeyState.CtrlPressed)
|
if (c.SpecialKeyState.CtrlPressed)
|
||||||
|
|
@ -82,9 +113,12 @@ namespace Wox.Plugin.Folder
|
||||||
}
|
}
|
||||||
|
|
||||||
string changeTo = path.EndsWith("\\") ? path : path + "\\";
|
string changeTo = path.EndsWith("\\") ? path : path + "\\";
|
||||||
_context.API.ChangeQuery(string.IsNullOrEmpty(queryActionKeyword)? changeTo : queryActionKeyword + " " + changeTo);
|
_context.API.ChangeQuery(string.IsNullOrEmpty(query.ActionKeyword) ?
|
||||||
|
changeTo :
|
||||||
|
query.ActionKeyword + " " + changeTo);
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
|
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,8 +127,8 @@ namespace Wox.Plugin.Folder
|
||||||
string search = query.Search.ToLower();
|
string search = query.Search.ToLower();
|
||||||
var userFolderLinks = _settings.FolderLinks.Where(
|
var userFolderLinks = _settings.FolderLinks.Where(
|
||||||
x => x.Nickname.StartsWith(search, StringComparison.OrdinalIgnoreCase));
|
x => x.Nickname.StartsWith(search, StringComparison.OrdinalIgnoreCase));
|
||||||
var results = userFolderLinks.Select(item => CreateFolderResult(item.Nickname, item.Path, query.ActionKeyword))
|
var results = userFolderLinks.Select(item =>
|
||||||
.ToList();
|
CreateFolderResult(item.Nickname, DefaultFolderSubtitleString, item.Path, query)).ToList();
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,48 +166,67 @@ namespace Wox.Plugin.Folder
|
||||||
incompleteName = search.Substring(index + 1).ToLower();
|
incompleteName = search.Substring(index + 1).ToLower();
|
||||||
search = search.Substring(0, index + 1);
|
search = search.Substring(0, index + 1);
|
||||||
if (!Directory.Exists(search))
|
if (!Directory.Exists(search))
|
||||||
|
{
|
||||||
return results;
|
return results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return results;
|
return results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // folder exist, add \ at the end of doesn't exist
|
{
|
||||||
|
// folder exist, add \ at the end of doesn't exist
|
||||||
if (!search.EndsWith("\\"))
|
if (!search.EndsWith("\\"))
|
||||||
|
{
|
||||||
search += "\\";
|
search += "\\";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results.Add(CreateOpenCurrentFolderResult(incompleteName, search));
|
results.Add(CreateOpenCurrentFolderResult(incompleteName, search));
|
||||||
|
|
||||||
|
var searchOption = SearchOption.TopDirectoryOnly;
|
||||||
var directoryInfo = new DirectoryInfo(search);
|
|
||||||
|
|
||||||
var searchOption= SearchOption.TopDirectoryOnly;
|
|
||||||
incompleteName += "*";
|
incompleteName += "*";
|
||||||
|
|
||||||
if (incompleteName.StartsWith(">")) // give the ability to search all folder when starting with >
|
// give the ability to search all folder when starting with >
|
||||||
|
if (incompleteName.StartsWith(">"))
|
||||||
{
|
{
|
||||||
searchOption = SearchOption.AllDirectories;
|
searchOption = SearchOption.AllDirectories;
|
||||||
incompleteName = incompleteName.Substring(1);
|
|
||||||
|
// match everything before and after search term using supported wildcard '*', ie. *searchterm*
|
||||||
|
incompleteName = "*" + incompleteName.Substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var folderList = new List<Result>();
|
||||||
|
var fileList = new List<Result>();
|
||||||
|
|
||||||
|
var folderSubtitleString = DefaultFolderSubtitleString;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// search folder and add results
|
// search folder and add results
|
||||||
|
var directoryInfo = new DirectoryInfo(search);
|
||||||
var fileSystemInfos = directoryInfo.GetFileSystemInfos(incompleteName, searchOption);
|
var fileSystemInfos = directoryInfo.GetFileSystemInfos(incompleteName, searchOption);
|
||||||
|
|
||||||
foreach (var fileSystemInfo in fileSystemInfos)
|
foreach (var fileSystemInfo in fileSystemInfos)
|
||||||
{
|
{
|
||||||
if ((fileSystemInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue;
|
if ((fileSystemInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue;
|
||||||
|
|
||||||
var result =
|
if(fileSystemInfo is DirectoryInfo)
|
||||||
fileSystemInfo is DirectoryInfo
|
{
|
||||||
? CreateFolderResult(fileSystemInfo.Name, fileSystemInfo.FullName, query.ActionKeyword)
|
if (searchOption == SearchOption.AllDirectories)
|
||||||
: CreateFileResult(fileSystemInfo.FullName);
|
folderSubtitleString = fileSystemInfo.FullName;
|
||||||
results.Add(result);
|
|
||||||
|
folderList.Add(CreateFolderResult(fileSystemInfo.Name, folderSubtitleString, fileSystemInfo.FullName, query));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileList.Add(CreateFileResult(fileSystemInfo.FullName, query));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (e is UnauthorizedAccessException || e is ArgumentException)
|
if (e is UnauthorizedAccessException || e is ArgumentException)
|
||||||
{
|
{
|
||||||
|
|
@ -185,15 +238,18 @@ namespace Wox.Plugin.Folder
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
// Intial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection.
|
||||||
|
return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Result CreateFileResult(string filePath)
|
private static Result CreateFileResult(string filePath, Query query)
|
||||||
{
|
{
|
||||||
var result = new Result
|
var result = new Result
|
||||||
{
|
{
|
||||||
Title = Path.GetFileName(filePath),
|
Title = Path.GetFileName(filePath),
|
||||||
|
SubTitle = filePath,
|
||||||
IcoPath = filePath,
|
IcoPath = filePath,
|
||||||
|
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, Path.GetFileName(filePath)).MatchData,
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -206,7 +262,8 @@ namespace Wox.Plugin.Folder
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
},
|
||||||
|
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath}
|
||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -243,5 +300,10 @@ namespace Wox.Plugin.Folder
|
||||||
{
|
{
|
||||||
return _context.API.GetTranslation("wox_plugin_folder_plugin_description");
|
return _context.API.GetTranslation("wox_plugin_folder_plugin_description");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Result> LoadContextMenus(Result selectedResult)
|
||||||
|
{
|
||||||
|
return _contextMenuLoader.LoadContextMenus(selectedResult);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -58,6 +58,7 @@
|
||||||
<Compile Include="..\..\SolutionAssemblyInfo.cs">
|
<Compile Include="..\..\SolutionAssemblyInfo.cs">
|
||||||
<Link>Properties\SolutionAssemblyInfo.cs</Link>
|
<Link>Properties\SolutionAssemblyInfo.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="ContextMenuLoader.cs" />
|
||||||
<Compile Include="FolderLink.cs" />
|
<Compile Include="FolderLink.cs" />
|
||||||
<Compile Include="Main.cs" />
|
<Compile Include="Main.cs" />
|
||||||
<Compile Include="FolderPluginSettings.xaml.cs">
|
<Compile Include="FolderPluginSettings.xaml.cs">
|
||||||
|
|
@ -67,7 +68,6 @@
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -80,6 +80,15 @@
|
||||||
<None Include="Images\copy.png">
|
<None Include="Images\copy.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="Images\deletefilefolder.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<Content Include="Images\file.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<None Include="Images\user.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<Content Include="Languages\en.xaml">
|
<Content Include="Languages\en.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
|
@ -126,6 +135,17 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>9.0.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -33,10 +33,6 @@
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="JetBrains.Annotations, Version=10.3.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\JetBrains.Annotations.10.3.0\lib\net\JetBrains.Annotations.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
|
@ -49,7 +45,6 @@
|
||||||
<Compile Include="Main.cs" />
|
<Compile Include="Main.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -115,6 +110,14 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -8,6 +8,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Wox.Infrastructure;
|
||||||
using Wox.Infrastructure.Http;
|
using Wox.Infrastructure.Http;
|
||||||
using Wox.Infrastructure.Logger;
|
using Wox.Infrastructure.Logger;
|
||||||
|
|
||||||
|
|
@ -142,6 +143,8 @@ namespace Wox.Plugin.PluginManagement
|
||||||
Title = r.name,
|
Title = r.name,
|
||||||
SubTitle = r.description,
|
SubTitle = r.description,
|
||||||
IcoPath = "Images\\plugin.png",
|
IcoPath = "Images\\plugin.png",
|
||||||
|
TitleHighlightData = StringMatcher.FuzzySearch(query.SecondSearch, r.name).MatchData,
|
||||||
|
SubTitleHighlightData = StringMatcher.FuzzySearch(query.SecondSearch, r.description).MatchData,
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
MessageBoxResult result = MessageBox.Show("Are you sure you wish to install the \'" + r.name + "\' plugin",
|
MessageBoxResult result = MessageBox.Show("Are you sure you wish to install the \'" + r.name + "\' plugin",
|
||||||
|
|
@ -191,6 +194,8 @@ namespace Wox.Plugin.PluginManagement
|
||||||
Title = plugin.Name,
|
Title = plugin.Name,
|
||||||
SubTitle = plugin.Description,
|
SubTitle = plugin.Description,
|
||||||
IcoPath = plugin.IcoPath,
|
IcoPath = plugin.IcoPath,
|
||||||
|
TitleHighlightData = StringMatcher.FuzzySearch(query.SecondSearch, plugin.Name).MatchData,
|
||||||
|
SubTitleHighlightData = StringMatcher.FuzzySearch(query.SecondSearch, plugin.Description).MatchData,
|
||||||
Action = e =>
|
Action = e =>
|
||||||
{
|
{
|
||||||
UnInstallPlugin(plugin);
|
UnInstallPlugin(plugin);
|
||||||
|
|
|
||||||
|
|
@ -34,14 +34,6 @@
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="JetBrains.Annotations, Version=10.3.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\JetBrains.Annotations.10.3.0\lib\net\JetBrains.Annotations.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
|
@ -68,7 +60,6 @@
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -120,6 +111,17 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>9.0.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
BIN
Plugins/Wox.Plugin.Program/Images/user.png
Normal file
BIN
Plugins/Wox.Plugin.Program/Images/user.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
|
|
@ -31,6 +31,7 @@
|
||||||
<system:String x:Key="wox_plugin_program_update_file_suffixes">Successfully updated file suffixes</system:String>
|
<system:String x:Key="wox_plugin_program_update_file_suffixes">Successfully updated file suffixes</system:String>
|
||||||
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">File suffixes can't be empty</system:String>
|
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">File suffixes can't be empty</system:String>
|
||||||
|
|
||||||
|
<system:String x:Key="wox_plugin_program_run_as_different_user">Run As Different User</system:String>
|
||||||
<system:String x:Key="wox_plugin_program_run_as_administrator">Run As Administrator</system:String>
|
<system:String x:Key="wox_plugin_program_run_as_administrator">Run As Administrator</system:String>
|
||||||
<system:String x:Key="wox_plugin_program_open_containing_folder">Open containing folder</system:String>
|
<system:String x:Key="wox_plugin_program_open_containing_folder">Open containing folder</system:String>
|
||||||
<system:String x:Key="wox_plugin_program_disable_program">Disable this program from displaying</system:String>
|
<system:String x:Key="wox_plugin_program_disable_program">Disable this program from displaying</system:String>
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,8 @@ namespace Wox.Plugin.Program
|
||||||
}
|
}
|
||||||
|
|
||||||
var results1 = win32.AsParallel()
|
var results1 = win32.AsParallel()
|
||||||
.Where(p => p.Enabled)
|
.Where(p => p.Enabled)
|
||||||
.Select(p => p.Result(query.Search, _context.API));
|
.Select(p => p.Result(query.Search, _context.API));
|
||||||
|
|
||||||
var results2 = uwps.AsParallel()
|
var results2 = uwps.AsParallel()
|
||||||
.Where(p => p.Enabled)
|
.Where(p => p.Enabled)
|
||||||
|
|
@ -191,22 +191,19 @@ namespace Wox.Plugin.Program
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool StartProcess(ProcessStartInfo info)
|
public static void StartProcess(Func<ProcessStartInfo, Process> runProcess, ProcessStartInfo info)
|
||||||
{
|
{
|
||||||
bool hide;
|
bool hide;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Process.Start(info);
|
runProcess(info);
|
||||||
hide = true;
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
var name = "Plugin: Program";
|
var name = "Plugin: Program";
|
||||||
var message = $"Can't start: {info.FileName}";
|
var message = $"Unable to start: {info.FileName}";
|
||||||
_context.API.ShowMsg(name, message, string.Empty);
|
_context.API.ShowMsg(name, message, string.Empty);
|
||||||
hide = false;
|
|
||||||
}
|
}
|
||||||
return hide;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReloadData()
|
public void ReloadData()
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ namespace Wox.Plugin.Program.Programs
|
||||||
|
|
||||||
public UWP(Package package)
|
public UWP(Package package)
|
||||||
{
|
{
|
||||||
|
|
||||||
Location = package.InstalledLocation.Path;
|
Location = package.InstalledLocation.Path;
|
||||||
Name = package.Id.Name;
|
Name = package.Id.Name;
|
||||||
FullName = package.Id.FullName;
|
FullName = package.Id.FullName;
|
||||||
|
|
@ -266,11 +265,9 @@ namespace Wox.Plugin.Program.Programs
|
||||||
|
|
||||||
private int Score(string query)
|
private int Score(string query)
|
||||||
{
|
{
|
||||||
var score1 = StringMatcher.FuzzySearch(query, DisplayName).ScoreAfterSearchPrecisionFilter();
|
var displayNameMatch = StringMatcher.FuzzySearch(query, DisplayName);
|
||||||
var score2 = StringMatcher.ScoreForPinyin(DisplayName, query);
|
var descriptionMatch = StringMatcher.FuzzySearch(query, Description);
|
||||||
var score3 = StringMatcher.FuzzySearch(query, Description).ScoreAfterSearchPrecisionFilter();
|
var score = new[] { displayNameMatch.Score, descriptionMatch.Score }.Max();
|
||||||
var score4 = StringMatcher.ScoreForPinyin(Description, query);
|
|
||||||
var score = new[] { score1, score2, score3, score4 }.Max();
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,14 +296,18 @@ namespace Wox.Plugin.Program.Programs
|
||||||
Description.Substring(0, DisplayName.Length) == DisplayName)
|
Description.Substring(0, DisplayName.Length) == DisplayName)
|
||||||
{
|
{
|
||||||
result.Title = Description;
|
result.Title = Description;
|
||||||
|
result.TitleHighlightData = StringMatcher.FuzzySearch(query, Description).MatchData;
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrEmpty(Description))
|
else if (!string.IsNullOrEmpty(Description))
|
||||||
{
|
{
|
||||||
result.Title = $"{DisplayName}: {Description}";
|
var title = $"{DisplayName}: {Description}";
|
||||||
|
result.Title = title;
|
||||||
|
result.TitleHighlightData = StringMatcher.FuzzySearch(query, title).MatchData;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result.Title = DisplayName;
|
result.Title = DisplayName;
|
||||||
|
result.TitleHighlightData = StringMatcher.FuzzySearch(query, DisplayName).MatchData;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -318,11 +319,14 @@ namespace Wox.Plugin.Program.Programs
|
||||||
new Result
|
new Result
|
||||||
{
|
{
|
||||||
Title = api.GetTranslation("wox_plugin_program_open_containing_folder"),
|
Title = api.GetTranslation("wox_plugin_program_open_containing_folder"),
|
||||||
|
|
||||||
Action = _ =>
|
Action = _ =>
|
||||||
{
|
{
|
||||||
var hide = Main.StartProcess(new ProcessStartInfo(Package.Location));
|
Main.StartProcess(Process.Start, new ProcessStartInfo(Package.Location));
|
||||||
return hide;
|
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
IcoPath = "Images/folder.png"
|
IcoPath = "Images/folder.png"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,12 @@ using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using Shell;
|
using Shell;
|
||||||
using Wox.Infrastructure;
|
using Wox.Infrastructure;
|
||||||
using Wox.Plugin.Program.Logger;
|
using Wox.Plugin.Program.Logger;
|
||||||
|
using Wox.Plugin.SharedCommands;
|
||||||
|
|
||||||
namespace Wox.Plugin.Program.Programs
|
namespace Wox.Plugin.Program.Programs
|
||||||
{
|
{
|
||||||
|
|
@ -33,12 +35,10 @@ namespace Wox.Plugin.Program.Programs
|
||||||
|
|
||||||
private int Score(string query)
|
private int Score(string query)
|
||||||
{
|
{
|
||||||
var score1 = StringMatcher.FuzzySearch(query, Name).ScoreAfterSearchPrecisionFilter();
|
var nameMatch = StringMatcher.FuzzySearch(query, Name);
|
||||||
var score2 = StringMatcher.ScoreForPinyin(Name, query);
|
var descriptionMatch = StringMatcher.FuzzySearch(query, Description);
|
||||||
var score3 = StringMatcher.FuzzySearch(query, Description).ScoreAfterSearchPrecisionFilter();
|
var executableNameMatch = StringMatcher.FuzzySearch(query, ExecutableName);
|
||||||
var score4 = StringMatcher.ScoreForPinyin(Description, query);
|
var score = new[] { nameMatch.Score, descriptionMatch.Score, executableNameMatch.Score }.Max();
|
||||||
var score5 = StringMatcher.FuzzySearch(query, ExecutableName).ScoreAfterSearchPrecisionFilter();
|
|
||||||
var score = new[] { score1, score2, score3, score4, score5 }.Max();
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,8 +64,10 @@ namespace Wox.Plugin.Program.Programs
|
||||||
FileName = FullPath,
|
FileName = FullPath,
|
||||||
WorkingDirectory = ParentDirectory
|
WorkingDirectory = ParentDirectory
|
||||||
};
|
};
|
||||||
var hide = Main.StartProcess(info);
|
|
||||||
return hide;
|
Main.StartProcess(Process.Start, info);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -73,14 +75,18 @@ namespace Wox.Plugin.Program.Programs
|
||||||
Description.Substring(0, Name.Length) == Name)
|
Description.Substring(0, Name.Length) == Name)
|
||||||
{
|
{
|
||||||
result.Title = Description;
|
result.Title = Description;
|
||||||
|
result.TitleHighlightData = StringMatcher.FuzzySearch(query, Description).MatchData;
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrEmpty(Description))
|
else if (!string.IsNullOrEmpty(Description))
|
||||||
{
|
{
|
||||||
result.Title = $"{Name}: {Description}";
|
var title = $"{Name}: {Description}";
|
||||||
|
result.Title = title;
|
||||||
|
result.TitleHighlightData = StringMatcher.FuzzySearch(query, title).MatchData;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result.Title = Name;
|
result.Title = Name;
|
||||||
|
result.TitleHighlightData = StringMatcher.FuzzySearch(query, Name).MatchData;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -91,6 +97,19 @@ namespace Wox.Plugin.Program.Programs
|
||||||
{
|
{
|
||||||
var contextMenus = new List<Result>
|
var contextMenus = new List<Result>
|
||||||
{
|
{
|
||||||
|
new Result
|
||||||
|
{
|
||||||
|
Title = api.GetTranslation("wox_plugin_program_run_as_different_user"),
|
||||||
|
Action = _ =>
|
||||||
|
{
|
||||||
|
var info = FullPath.SetProcessStartInfo(ParentDirectory);
|
||||||
|
|
||||||
|
Task.Run(() => Main.StartProcess(ShellCommand.RunAsDifferentUser, info));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
IcoPath = "Images/user.png"
|
||||||
|
},
|
||||||
new Result
|
new Result
|
||||||
{
|
{
|
||||||
Title = api.GetTranslation("wox_plugin_program_run_as_administrator"),
|
Title = api.GetTranslation("wox_plugin_program_run_as_administrator"),
|
||||||
|
|
@ -102,8 +121,10 @@ namespace Wox.Plugin.Program.Programs
|
||||||
WorkingDirectory = ParentDirectory,
|
WorkingDirectory = ParentDirectory,
|
||||||
Verb = "runas"
|
Verb = "runas"
|
||||||
};
|
};
|
||||||
var hide = Main.StartProcess(info);
|
|
||||||
return hide;
|
Task.Run(() => Main.StartProcess(Process.Start, info));
|
||||||
|
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
IcoPath = "Images/cmd.png"
|
IcoPath = "Images/cmd.png"
|
||||||
},
|
},
|
||||||
|
|
@ -112,8 +133,9 @@ namespace Wox.Plugin.Program.Programs
|
||||||
Title = api.GetTranslation("wox_plugin_program_open_containing_folder"),
|
Title = api.GetTranslation("wox_plugin_program_open_containing_folder"),
|
||||||
Action = _ =>
|
Action = _ =>
|
||||||
{
|
{
|
||||||
var hide = Main.StartProcess(new ProcessStartInfo(ParentDirectory));
|
Main.StartProcess(Process.Start, new ProcessStartInfo(ParentDirectory));
|
||||||
return hide;
|
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
IcoPath = "Images/folder.png"
|
IcoPath = "Images/folder.png"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,18 +40,7 @@
|
||||||
<HintPath>.\AppxPackagingTlb.dll</HintPath>
|
<HintPath>.\AppxPackagingTlb.dll</HintPath>
|
||||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="JetBrains.Annotations, Version=10.3.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\JetBrains.Annotations.10.3.0\lib\net\JetBrains.Annotations.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\NLog.4.2.0\lib\net45\NLog.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="ShObjIdlTlb">
|
<Reference Include="ShObjIdlTlb">
|
||||||
|
|
@ -94,7 +83,6 @@
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -112,6 +100,9 @@
|
||||||
<None Include="Images\disable.png">
|
<None Include="Images\disable.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="Images\user.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<Content Include="Languages\en.xaml">
|
<Content Include="Languages\en.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
|
@ -163,14 +154,24 @@
|
||||||
<Name>Wox.Plugin</Name>
|
<Name>Wox.Plugin</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>9.0.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NLog">
|
||||||
|
<Version>4.2.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="UwpDesktop">
|
||||||
|
<Version>10.0.14393.3</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="..\..\packages\UwpDesktop.10.0.14393.3\build\portable-net45+uap\UwpDesktop.targets" Condition="Exists('..\..\packages\UwpDesktop.10.0.14393.3\build\portable-net45+uap\UwpDesktop.targets')" />
|
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Error Condition="!Exists('..\..\packages\UwpDesktop.10.0.14393.3\build\portable-net45+uap\UwpDesktop.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\UwpDesktop.10.0.14393.3\build\portable-net45+uap\UwpDesktop.targets'))" />
|
|
||||||
</Target>
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
|
||||||
<package id="NLog" version="4.2.0" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
<package id="UwpDesktop" version="10.0.14393.3" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
BIN
Plugins/Wox.Plugin.Shell/Images/user.png
Normal file
BIN
Plugins/Wox.Plugin.Shell/Images/user.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
<system:String x:Key="wox_plugin_cmd_relace_winr">Replace Win+R</system:String>
|
<system:String x:Key="wox_plugin_cmd_relace_winr">Replace Win+R</system:String>
|
||||||
<system:String x:Key="wox_plugin_cmd_leave_cmd_open">Do not close Command Prompt after command execution</system:String>
|
<system:String x:Key="wox_plugin_cmd_leave_cmd_open">Do not close Command Prompt after command execution</system:String>
|
||||||
|
<system:String x:Key="wox_plugin_cmd_always_run_as_administrator">Always run as administrator</system:String>
|
||||||
|
<system:String x:Key="wox_plugin_cmd_run_as_different_user">Run as different user</system:String>
|
||||||
<system:String x:Key="wox_plugin_cmd_plugin_name">Shell</system:String>
|
<system:String x:Key="wox_plugin_cmd_plugin_name">Shell</system:String>
|
||||||
<system:String x:Key="wox_plugin_cmd_plugin_description">Allows to execute system commands from Wox. Commands should start with ></system:String>
|
<system:String x:Key="wox_plugin_cmd_plugin_description">Allows to execute system commands from Wox. Commands should start with ></system:String>
|
||||||
<system:String x:Key="wox_plugin_cmd_cmd_has_been_executed_times">this command has been executed {0} times</system:String>
|
<system:String x:Key="wox_plugin_cmd_cmd_has_been_executed_times">this command has been executed {0} times</system:String>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using WindowsInput;
|
using WindowsInput;
|
||||||
using WindowsInput.Native;
|
using WindowsInput.Native;
|
||||||
using Wox.Infrastructure.Hotkey;
|
using Wox.Infrastructure.Hotkey;
|
||||||
using Wox.Infrastructure.Logger;
|
using Wox.Infrastructure.Logger;
|
||||||
using Wox.Infrastructure.Storage;
|
using Wox.Infrastructure.Storage;
|
||||||
|
using Wox.Plugin.SharedCommands;
|
||||||
using Application = System.Windows.Application;
|
using Application = System.Windows.Application;
|
||||||
using Control = System.Windows.Controls.Control;
|
using Control = System.Windows.Controls.Control;
|
||||||
using Keys = System.Windows.Forms.Keys;
|
using Keys = System.Windows.Forms.Keys;
|
||||||
|
|
@ -83,7 +86,7 @@ namespace Wox.Plugin.Shell
|
||||||
IcoPath = Image,
|
IcoPath = Image,
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
Execute(m);
|
Execute(Process.Start, PrepareProcessStartInfo(m));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
@ -116,7 +119,7 @@ namespace Wox.Plugin.Shell
|
||||||
IcoPath = Image,
|
IcoPath = Image,
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
Execute(m.Key);
|
Execute(Process.Start, PrepareProcessStartInfo(m.Key));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -135,7 +138,7 @@ namespace Wox.Plugin.Shell
|
||||||
IcoPath = Image,
|
IcoPath = Image,
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
Execute(cmd);
|
Execute(Process.Start, PrepareProcessStartInfo(cmd));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -153,27 +156,26 @@ namespace Wox.Plugin.Shell
|
||||||
IcoPath = Image,
|
IcoPath = Image,
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
Execute(m.Key);
|
Execute(Process.Start, PrepareProcessStartInfo(m.Key));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}).Take(5);
|
}).Take(5);
|
||||||
return history.ToList();
|
return history.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Execute(string command, bool runAsAdministrator = false)
|
private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdministrator = false)
|
||||||
{
|
{
|
||||||
command = command.Trim();
|
command = command.Trim();
|
||||||
command = Environment.ExpandEnvironmentVariables(command);
|
command = Environment.ExpandEnvironmentVariables(command);
|
||||||
|
var workingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||||
|
var runAsAdministratorArg = !runAsAdministrator && !_settings.RunAsAdministrator ? "" : "runas";
|
||||||
|
|
||||||
ProcessStartInfo info;
|
ProcessStartInfo info;
|
||||||
if (_settings.Shell == Shell.Cmd)
|
if (_settings.Shell == Shell.Cmd)
|
||||||
{
|
{
|
||||||
var arguments = _settings.LeaveShellOpen ? $"/k \"{command}\"" : $"/c \"{command}\" & pause";
|
var arguments = _settings.LeaveShellOpen ? $"/k \"{command}\"" : $"/c \"{command}\" & pause";
|
||||||
info = new ProcessStartInfo
|
|
||||||
{
|
info = ShellCommand.SetProcessStartInfo("cmd.exe", workingDirectory, arguments, runAsAdministratorArg);
|
||||||
FileName = "cmd.exe",
|
|
||||||
Arguments = arguments,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else if (_settings.Shell == Shell.Powershell)
|
else if (_settings.Shell == Shell.Powershell)
|
||||||
{
|
{
|
||||||
|
|
@ -186,11 +188,8 @@ namespace Wox.Plugin.Shell
|
||||||
{
|
{
|
||||||
arguments = $"\"{command} ; Read-Host -Prompt \\\"Press Enter to continue\\\"\"";
|
arguments = $"\"{command} ; Read-Host -Prompt \\\"Press Enter to continue\\\"\"";
|
||||||
}
|
}
|
||||||
info = new ProcessStartInfo
|
|
||||||
{
|
info = ShellCommand.SetProcessStartInfo("powershell.exe", workingDirectory, arguments, runAsAdministratorArg);
|
||||||
FileName = "powershell.exe",
|
|
||||||
Arguments = arguments
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else if (_settings.Shell == Shell.RunCommand)
|
else if (_settings.Shell == Shell.RunCommand)
|
||||||
{
|
{
|
||||||
|
|
@ -200,41 +199,48 @@ namespace Wox.Plugin.Shell
|
||||||
var filename = parts[0];
|
var filename = parts[0];
|
||||||
if (ExistInPath(filename))
|
if (ExistInPath(filename))
|
||||||
{
|
{
|
||||||
var arguemtns = parts[1];
|
var arguments = parts[1];
|
||||||
info = new ProcessStartInfo
|
info = ShellCommand.SetProcessStartInfo(filename, workingDirectory, arguments, runAsAdministratorArg);
|
||||||
{
|
|
||||||
FileName = filename,
|
|
||||||
Arguments = arguemtns
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info = new ProcessStartInfo(command);
|
info = ShellCommand.SetProcessStartInfo(command, verb: runAsAdministratorArg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info = new ProcessStartInfo(command);
|
info = ShellCommand.SetProcessStartInfo(command, verb: runAsAdministratorArg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return;
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
info.UseShellExecute = true;
|
info.UseShellExecute = true;
|
||||||
info.WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
|
||||||
info.Verb = runAsAdministrator ? "runas" : "";
|
|
||||||
|
|
||||||
|
_settings.AddCmdHistory(command);
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Execute(Func<ProcessStartInfo, Process> startProcess,ProcessStartInfo info)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Process.Start(info);
|
startProcess(info);
|
||||||
_settings.AddCmdHistory(command);
|
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException e)
|
catch (FileNotFoundException e)
|
||||||
{
|
{
|
||||||
MessageBox.Show($"Command not found: {e.Message}");
|
var name = "Plugin: Shell";
|
||||||
|
var message = $"Command not found: {e.Message}";
|
||||||
|
_context.API.ShowMsg(name, message);
|
||||||
|
}
|
||||||
|
catch(Win32Exception e)
|
||||||
|
{
|
||||||
|
var name = "Plugin: Shell";
|
||||||
|
var message = $"Error running the command: {e.Message}";
|
||||||
|
_context.API.ShowMsg(name, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -316,19 +322,31 @@ namespace Wox.Plugin.Shell
|
||||||
|
|
||||||
public List<Result> LoadContextMenus(Result selectedResult)
|
public List<Result> LoadContextMenus(Result selectedResult)
|
||||||
{
|
{
|
||||||
return new List<Result>
|
var resultlist = new List<Result>
|
||||||
{
|
{
|
||||||
new Result
|
new Result
|
||||||
{
|
{
|
||||||
Title = _context.API.GetTranslation("wox_plugin_cmd_run_as_administrator"),
|
Title = _context.API.GetTranslation("wox_plugin_cmd_run_as_different_user"),
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
Execute(selectedResult.Title, true);
|
Task.Run(() =>Execute(ShellCommand.RunAsDifferentUser, PrepareProcessStartInfo(selectedResult.Title)));
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
IcoPath = Image
|
IcoPath = "Images/user.png"
|
||||||
}
|
},
|
||||||
};
|
new Result
|
||||||
|
{
|
||||||
|
Title = _context.API.GetTranslation("wox_plugin_cmd_run_as_administrator"),
|
||||||
|
Action = c =>
|
||||||
|
{
|
||||||
|
Execute(Process.Start, PrepareProcessStartInfo(selectedResult.Title, true));
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
IcoPath = Image
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return resultlist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ namespace Wox.Plugin.Shell
|
||||||
public Shell Shell { get; set; } = Shell.Cmd;
|
public Shell Shell { get; set; } = Shell.Cmd;
|
||||||
public bool ReplaceWinR { get; set; } = true;
|
public bool ReplaceWinR { get; set; } = true;
|
||||||
public bool LeaveShellOpen { get; set; }
|
public bool LeaveShellOpen { get; set; }
|
||||||
|
public bool RunAsAdministrator { get; set; } = true;
|
||||||
|
|
||||||
public Dictionary<string, int> Count = new Dictionary<string, int>();
|
public Dictionary<string, int> Count = new Dictionary<string, int>();
|
||||||
|
|
||||||
public void AddCmdHistory(string cmdName)
|
public void AddCmdHistory(string cmdName)
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,12 @@
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<CheckBox Grid.Row="0" x:Name="ReplaceWinR" Content="{DynamicResource wox_plugin_cmd_relace_winr}" Margin="10" HorizontalAlignment="Left"/>
|
<CheckBox Grid.Row="0" x:Name="ReplaceWinR" Content="{DynamicResource wox_plugin_cmd_relace_winr}" Margin="10" HorizontalAlignment="Left"/>
|
||||||
<CheckBox Grid.Row="1" x:Name="LeaveShellOpen" Content="{DynamicResource wox_plugin_cmd_leave_cmd_open}" Margin="10" HorizontalAlignment="Left"/>
|
<CheckBox Grid.Row="1" x:Name="LeaveShellOpen" Content="{DynamicResource wox_plugin_cmd_leave_cmd_open}" Margin="10" HorizontalAlignment="Left"/>
|
||||||
<ComboBox Grid.Row="2" x:Name="ShellComboBox" Margin="10" HorizontalAlignment="Left" >
|
<CheckBox Grid.Row="2" x:Name="AlwaysRunAsAdministrator" Content="{DynamicResource wox_plugin_cmd_always_run_as_administrator}" Margin="10" HorizontalAlignment="Left"/>
|
||||||
|
<ComboBox Grid.Row="3" x:Name="ShellComboBox" Margin="10" HorizontalAlignment="Left" >
|
||||||
<ComboBoxItem>CMD</ComboBoxItem>
|
<ComboBoxItem>CMD</ComboBoxItem>
|
||||||
<ComboBoxItem>PowerShell</ComboBoxItem>
|
<ComboBoxItem>PowerShell</ComboBoxItem>
|
||||||
<ComboBoxItem>RunCommand</ComboBoxItem>
|
<ComboBoxItem>RunCommand</ComboBoxItem>
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ namespace Wox.Plugin.Shell
|
||||||
{
|
{
|
||||||
ReplaceWinR.IsChecked = _settings.ReplaceWinR;
|
ReplaceWinR.IsChecked = _settings.ReplaceWinR;
|
||||||
LeaveShellOpen.IsChecked = _settings.LeaveShellOpen;
|
LeaveShellOpen.IsChecked = _settings.LeaveShellOpen;
|
||||||
|
AlwaysRunAsAdministrator.IsChecked = _settings.RunAsAdministrator;
|
||||||
LeaveShellOpen.IsEnabled = _settings.Shell != Shell.RunCommand;
|
LeaveShellOpen.IsEnabled = _settings.Shell != Shell.RunCommand;
|
||||||
|
|
||||||
LeaveShellOpen.Checked += (o, e) =>
|
LeaveShellOpen.Checked += (o, e) =>
|
||||||
|
|
@ -29,6 +30,16 @@ namespace Wox.Plugin.Shell
|
||||||
_settings.LeaveShellOpen = false;
|
_settings.LeaveShellOpen = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AlwaysRunAsAdministrator.Checked += (o, e) =>
|
||||||
|
{
|
||||||
|
_settings.RunAsAdministrator = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
AlwaysRunAsAdministrator.Unchecked += (o, e) =>
|
||||||
|
{
|
||||||
|
_settings.RunAsAdministrator = false;
|
||||||
|
};
|
||||||
|
|
||||||
ReplaceWinR.Checked += (o, e) =>
|
ReplaceWinR.Checked += (o, e) =>
|
||||||
{
|
{
|
||||||
_settings.ReplaceWinR = true;
|
_settings.ReplaceWinR = true;
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,9 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="Images\user.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<Content Include="Languages\en.xaml">
|
<Content Include="Languages\en.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
|
@ -102,7 +105,6 @@
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -128,6 +130,20 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="InputSimulator">
|
||||||
|
<Version>1.0.4</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>9.0.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="InputSimulator" version="1.0.4.0" targetFramework="net452" />
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -56,12 +56,21 @@ namespace Wox.Plugin.Sys
|
||||||
var results = new List<Result>();
|
var results = new List<Result>();
|
||||||
foreach (var c in commands)
|
foreach (var c in commands)
|
||||||
{
|
{
|
||||||
var titleScore = StringMatcher.FuzzySearch(query.Search, c.Title).ScoreAfterSearchPrecisionFilter();
|
var titleMatch = StringMatcher.FuzzySearch(query.Search, c.Title);
|
||||||
var subTitleScore = StringMatcher.FuzzySearch(query.Search, c.SubTitle).ScoreAfterSearchPrecisionFilter();
|
var subTitleMatch = StringMatcher.FuzzySearch(query.Search, c.SubTitle);
|
||||||
var score = Math.Max(titleScore, subTitleScore);
|
|
||||||
|
var score = Math.Max(titleMatch.Score, subTitleMatch.Score);
|
||||||
if (score > 0)
|
if (score > 0)
|
||||||
{
|
{
|
||||||
c.Score = score;
|
c.Score = score;
|
||||||
|
if (score == titleMatch.Score)
|
||||||
|
{
|
||||||
|
c.TitleHighlightData = titleMatch.MatchData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c.SubTitleHighlightData = subTitleMatch.MatchData;
|
||||||
|
}
|
||||||
results.Add(c);
|
results.Add(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,6 @@
|
||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -146,6 +145,14 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Images\Images\" />
|
<Folder Include="Images\Images\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -56,7 +56,6 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -122,6 +121,14 @@
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -34,14 +34,6 @@
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="JetBrains.Annotations, Version=10.3.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\JetBrains.Annotations.10.3.0\lib\net\JetBrains.Annotations.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
|
@ -183,7 +175,6 @@
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="plugin.json">
|
<None Include="plugin.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -193,6 +184,17 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>9.0.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
WoX
|
WoX
|
||||||
===
|
===
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/jjw24/Wox/releases/latest)
|
[](https://github.com/jjw24/Wox/releases/latest)
|
||||||

|

|
||||||

|

|
||||||
[](https://ci.appveyor.com/project/happlebao/wox/branch/master)
|
[](https://dev.azure.com/Wox-Launcher/Wox/_build/latest?definitionId=1&branchName=master)
|
||||||
[](https://github.com/Wox-launcher/Wox/releases)
|
[](https://github.com/jjw24/Wox/releases)
|
||||||
[](https://github.com/LunaGao/BlessYourCodeTag)
|
[](https://github.com/LunaGao/BlessYourCodeTag)
|
||||||
|
|
||||||
**WoX** is a launcher for Windows that simply works. It's an alternative to [Alfred](https://www.alfredapp.com/) and [Launchy](http://www.launchy.net/). You can call it Windows omni-eXecutor if you want a long name.
|
**WoX** is a launcher for Windows that simply works. It's an alternative to [Alfred](https://www.alfredapp.com/) and [Launchy](http://www.launchy.net/). You can call it Windows omni-eXecutor if you want a long name.
|
||||||
|
|
@ -49,6 +49,8 @@ Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
- Launch: <kbd>Alt</kbd>+<kbd>Space</kbd>
|
- Launch: <kbd>Alt</kbd>+<kbd>Space</kbd>
|
||||||
|
- Context Menu: <kbd>Ctrl</kbd>+<kbd>O</kbd>
|
||||||
|
- Cancel/Return: <kbd>Esc</kbd>
|
||||||
- Install/Uninstall plugin: type `wpm install/uninstall`
|
- Install/Uninstall plugin: type `wpm install/uninstall`
|
||||||
- Reset: delete `%APPDATA%\Wox`
|
- Reset: delete `%APPDATA%\Wox`
|
||||||
- Log: `%APPDATA%\Wox\Logs`
|
- Log: `%APPDATA%\Wox\Logs`
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -92,21 +93,36 @@ namespace Wox.Core.Plugin
|
||||||
Settings.UpdatePluginSettings(_metadatas);
|
Settings.UpdatePluginSettings(_metadatas);
|
||||||
AllPlugins = PluginsLoader.Plugins(_metadatas, Settings);
|
AllPlugins = PluginsLoader.Plugins(_metadatas, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call initialize for all plugins
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>return the list of failed to init plugins or null for none</returns>
|
||||||
public static void InitializePlugins(IPublicAPI api)
|
public static void InitializePlugins(IPublicAPI api)
|
||||||
{
|
{
|
||||||
API = api;
|
API = api;
|
||||||
|
var failedPlugins = new ConcurrentQueue<PluginPair>();
|
||||||
Parallel.ForEach(AllPlugins, pair =>
|
Parallel.ForEach(AllPlugins, pair =>
|
||||||
{
|
{
|
||||||
var milliseconds = Stopwatch.Debug($"|PluginManager.InitializePlugins|Init method time cost for <{pair.Metadata.Name}>", () =>
|
try
|
||||||
{
|
{
|
||||||
pair.Plugin.Init(new PluginInitContext
|
var milliseconds = Stopwatch.Debug($"|PluginManager.InitializePlugins|Init method time cost for <{pair.Metadata.Name}>", () =>
|
||||||
{
|
{
|
||||||
CurrentPluginMetadata = pair.Metadata,
|
pair.Plugin.Init(new PluginInitContext
|
||||||
API = API
|
{
|
||||||
|
CurrentPluginMetadata = pair.Metadata,
|
||||||
|
API = API
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
pair.Metadata.InitTime += milliseconds;
|
||||||
pair.Metadata.InitTime += milliseconds;
|
Log.Info($"|PluginManager.InitializePlugins|Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>");
|
||||||
Log.Info($"|PluginManager.InitializePlugins|Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>");
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Exception(nameof(PluginManager), $"Fail to Init plugin: {pair.Metadata.Name}", e);
|
||||||
|
pair.Metadata.Disabled = true; // TODO: not sure this really disable it later on
|
||||||
|
failedPlugins.Enqueue(pair);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_contextMenuPlugins = GetPluginsForInterface<IContextMenu>();
|
_contextMenuPlugins = GetPluginsForInterface<IContextMenu>();
|
||||||
|
|
@ -121,6 +137,11 @@ namespace Wox.Core.Plugin
|
||||||
.ForEach(x => NonGlobalPlugins[x] = plugin);
|
.ForEach(x => NonGlobalPlugins[x] = plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (failedPlugins.Any())
|
||||||
|
{
|
||||||
|
var failed = string.Join(",", failedPlugins.Select(x => x.Metadata.Name));
|
||||||
|
API.ShowMsg($"Fail to Init Plugins", $"Plugins: {failed} - fail to load and would be disabled, please contact plugin creator for help", "", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InstallPlugin(string path)
|
public static void InstallPlugin(string path)
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,23 @@ using Wox.Infrastructure.Logger;
|
||||||
|
|
||||||
namespace Wox.Core
|
namespace Wox.Core
|
||||||
{
|
{
|
||||||
public static class Updater
|
public class Updater
|
||||||
{
|
{
|
||||||
private static readonly Internationalization Translater = InternationalizationManager.Instance;
|
public string GitHubRepository { get; }
|
||||||
|
|
||||||
public static async Task UpdateApp()
|
public Updater(string gitHubRepository)
|
||||||
|
{
|
||||||
|
GitHubRepository = gitHubRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateApp()
|
||||||
{
|
{
|
||||||
UpdateManager m;
|
UpdateManager m;
|
||||||
UpdateInfo u;
|
UpdateInfo u;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m = await GitHubUpdateManager(Constant.Repository);
|
m = await GitHubUpdateManager(GitHubRepository);
|
||||||
}
|
}
|
||||||
catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException)
|
catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException)
|
||||||
{
|
{
|
||||||
|
|
@ -66,8 +71,8 @@ namespace Wox.Core
|
||||||
await m.ApplyReleases(u);
|
await m.ApplyReleases(u);
|
||||||
await m.CreateUninstallerRegistryEntry();
|
await m.CreateUninstallerRegistryEntry();
|
||||||
|
|
||||||
var newVersionTips = Translater.GetTranslation("newVersionTips");
|
var newVersionTips = this.NewVersinoTips(fr.Version.ToString());
|
||||||
newVersionTips = string.Format(newVersionTips, fr.Version);
|
|
||||||
MessageBox.Show(newVersionTips);
|
MessageBox.Show(newVersionTips);
|
||||||
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
|
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +95,7 @@ namespace Wox.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/Squirrel/Squirrel.Windows/blob/master/src/Squirrel/UpdateManager.Factory.cs
|
/// https://github.com/Squirrel/Squirrel.Windows/blob/master/src/Squirrel/UpdateManager.Factory.cs
|
||||||
private static async Task<UpdateManager> GitHubUpdateManager(string repository)
|
private async Task<UpdateManager> GitHubUpdateManager(string repository)
|
||||||
{
|
{
|
||||||
var uri = new Uri(repository);
|
var uri = new Uri(repository);
|
||||||
var api = $"https://api.github.com/repos{uri.AbsolutePath}/releases";
|
var api = $"https://api.github.com/repos{uri.AbsolutePath}/releases";
|
||||||
|
|
@ -109,7 +114,7 @@ namespace Wox.Core
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string NewVersinoTips(string version)
|
public string NewVersinoTips(string version)
|
||||||
{
|
{
|
||||||
var translater = InternationalizationManager.Instance;
|
var translater = InternationalizationManager.Instance;
|
||||||
var tips = string.Format(translater.GetTranslation("newVersionTips"), version);
|
var tips = string.Format(translater.GetTranslation("newVersionTips"), version);
|
||||||
|
|
|
||||||
|
|
@ -36,64 +36,8 @@
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="DeltaCompressionDotNet, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1d14d6e5194e7f4a, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="DeltaCompressionDotNet.MsDelta, Version=1.0.0.0, Culture=neutral, PublicKeyToken=46b2138a390abf55, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.MsDelta.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="DeltaCompressionDotNet.PatchApi, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3e8888ee913ed789, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.PatchApi.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\squirrel.windows.1.5.2\lib\Net45\ICSharpCode.SharpZipLib.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="JetBrains.Annotations, Version=10.3.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\JetBrains.Annotations.10.3.0\lib\net\JetBrains.Annotations.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Mdb.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Pdb.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil.Rocks, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Rocks.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="NuGet.Squirrel, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\squirrel.windows.1.5.2\lib\Net45\NuGet.Squirrel.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="PropertyChanged, Version=1.51.0.0, Culture=neutral, PublicKeyToken=ee3ee20bcf148ddd, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\PropertyChanged.Fody.1.51.0\lib\dotnet\PropertyChanged.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Squirrel, Version=1.5.2.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\squirrel.windows.1.5.2\lib\Net45\Squirrel.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
|
|
@ -128,7 +72,6 @@
|
||||||
<Compile Include="Resource\Theme.cs" />
|
<Compile Include="Resource\Theme.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="Plugin\README.md" />
|
<None Include="Plugin\README.md" />
|
||||||
<None Include="README.md" />
|
<None Include="README.md" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
@ -145,14 +88,31 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="FodyWeavers.xml" />
|
<Content Include="FodyWeavers.xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Fody">
|
||||||
|
<Version>1.29.2</Version>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>9.0.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="PropertyChanged.Fody">
|
||||||
|
<Version>1.51.0</Version>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="squirrel.windows">
|
||||||
|
<Version>1.5.2</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="..\packages\Fody.1.29.2\build\dotnet\Fody.targets" Condition="Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" />
|
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Error Condition="!Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.29.2\build\dotnet\Fody.targets'))" />
|
|
||||||
</Target>
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="DeltaCompressionDotNet" version="1.0.0" targetFramework="net452" />
|
|
||||||
<package id="Fody" version="1.29.2" targetFramework="net452" developmentDependency="true" />
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Mono.Cecil" version="0.9.6.1" targetFramework="net452" />
|
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
|
||||||
<package id="PropertyChanged.Fody" version="1.51.0" targetFramework="net452" developmentDependency="true" />
|
|
||||||
<package id="SharpZipLib" version="0.86.0" targetFramework="net452" />
|
|
||||||
<package id="Splat" version="1.6.2" targetFramework="net452" />
|
|
||||||
<package id="squirrel.windows" version="1.5.2" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -2,49 +2,95 @@
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using hyjiacan.util.p4n;
|
using hyjiacan.util.p4n;
|
||||||
using hyjiacan.util.p4n.format;
|
using hyjiacan.util.p4n.format;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Wox.Infrastructure.Logger;
|
using Wox.Infrastructure.Logger;
|
||||||
using Wox.Infrastructure.Storage;
|
using Wox.Infrastructure.Storage;
|
||||||
using Wox.Infrastructure.UserSettings;
|
using Wox.Infrastructure.UserSettings;
|
||||||
|
|
||||||
namespace Wox.Infrastructure
|
namespace Wox.Infrastructure
|
||||||
{
|
{
|
||||||
public static class Alphabet
|
public interface IAlphabet
|
||||||
{
|
{
|
||||||
private static readonly HanyuPinyinOutputFormat Format = new HanyuPinyinOutputFormat();
|
string Translate(string stringToTranslate);
|
||||||
private static ConcurrentDictionary<string, string[][]> PinyinCache;
|
}
|
||||||
private static BinaryStorage<ConcurrentDictionary<string, string[][]>> _pinyinStorage;
|
|
||||||
private static Settings _settings;
|
|
||||||
|
|
||||||
public static void Initialize(Settings settings)
|
public class Alphabet : IAlphabet
|
||||||
|
{
|
||||||
|
private readonly HanyuPinyinOutputFormat Format = new HanyuPinyinOutputFormat();
|
||||||
|
private ConcurrentDictionary<string, string[][]> PinyinCache;
|
||||||
|
private BinaryStorage<ConcurrentDictionary<string, string[][]>> _pinyinStorage;
|
||||||
|
private Settings _settings;
|
||||||
|
|
||||||
|
public void Initialize([NotNull] Settings settings)
|
||||||
|
{
|
||||||
|
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||||
|
InitializePinyinHelpers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializePinyinHelpers()
|
||||||
{
|
{
|
||||||
_settings = settings;
|
|
||||||
Format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
|
Format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
|
||||||
|
|
||||||
Stopwatch.Normal("|Wox.Infrastructure.Alphabet.Initialize|Preload pinyin cache", () =>
|
Stopwatch.Normal("|Wox.Infrastructure.Alphabet.Initialize|Preload pinyin cache", () =>
|
||||||
{
|
{
|
||||||
_pinyinStorage = new BinaryStorage<ConcurrentDictionary<string, string[][]>>("Pinyin");
|
_pinyinStorage = new BinaryStorage<ConcurrentDictionary<string, string[][]>>("Pinyin");
|
||||||
PinyinCache = _pinyinStorage.TryLoad(new ConcurrentDictionary<string, string[][]>());
|
PinyinCache = _pinyinStorage.TryLoad(new ConcurrentDictionary<string, string[][]>());
|
||||||
|
|
||||||
// force pinyin library static constructor initialize
|
// force pinyin library static constructor initialize
|
||||||
PinyinHelper.toHanyuPinyinStringArray('T', Format);
|
PinyinHelper.toHanyuPinyinStringArray('T', Format);
|
||||||
});
|
});
|
||||||
Log.Info($"|Wox.Infrastructure.Alphabet.Initialize|Number of preload pinyin combination<{PinyinCache.Count}>");
|
Log.Info($"|Wox.Infrastructure.Alphabet.Initialize|Number of preload pinyin combination<{PinyinCache.Count}>");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Save()
|
public string Translate(string str)
|
||||||
{
|
{
|
||||||
|
return ConvertChineseCharactersToPinyin(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ConvertChineseCharactersToPinyin(string source)
|
||||||
|
{
|
||||||
|
if (!_settings.ShouldUsePinyin)
|
||||||
|
return source;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(source))
|
||||||
|
return source;
|
||||||
|
|
||||||
|
if (!ContainsChinese(source))
|
||||||
|
return source;
|
||||||
|
|
||||||
|
var combination = PinyinCombination(source);
|
||||||
|
|
||||||
|
var pinyinArray=combination.Select(x => string.Join("", x));
|
||||||
|
var acronymArray = combination.Select(Acronym).Distinct();
|
||||||
|
|
||||||
|
var joinedSingleStringCombination = new StringBuilder();
|
||||||
|
var all = acronymArray.Concat(pinyinArray);
|
||||||
|
all.ToList().ForEach(x => joinedSingleStringCombination.Append(x));
|
||||||
|
|
||||||
|
return joinedSingleStringCombination.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
if (!_settings.ShouldUsePinyin)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
_pinyinStorage.Save(PinyinCache);
|
_pinyinStorage.Save(PinyinCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string[] EmptyStringArray = new string[0];
|
private static string[] EmptyStringArray = new string[0];
|
||||||
private static string[][] Empty2DStringArray = new string[0][];
|
private static string[][] Empty2DStringArray = new string[0][];
|
||||||
|
|
||||||
|
[Obsolete("Not accurate, eg 音乐 will not return yinyue but returns yinle ")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// replace chinese character with pinyin, non chinese character won't be modified
|
/// replace chinese character with pinyin, non chinese character won't be modified
|
||||||
/// <param name="word"> should be word or sentence, instead of single character. e.g. 微软 </param>
|
/// <param name="word"> should be word or sentence, instead of single character. e.g. 微软 </param>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string[] Pinyin(string word)
|
public string[] Pinyin(string word)
|
||||||
{
|
{
|
||||||
if (!_settings.ShouldUsePinyin)
|
if (!_settings.ShouldUsePinyin)
|
||||||
{
|
{
|
||||||
|
|
@ -66,51 +112,48 @@ namespace Wox.Infrastructure
|
||||||
/// e.g. 音乐 will return yinyue and yinle
|
/// e.g. 音乐 will return yinyue and yinle
|
||||||
/// <param name="characters"> should be word or sentence, instead of single character. e.g. 微软 </param>
|
/// <param name="characters"> should be word or sentence, instead of single character. e.g. 微软 </param>
|
||||||
/// </summmary>
|
/// </summmary>
|
||||||
public static string[][] PinyinComination(string characters)
|
public string[][] PinyinCombination(string characters)
|
||||||
{
|
{
|
||||||
if (_settings.ShouldUsePinyin && !string.IsNullOrEmpty(characters))
|
if (!_settings.ShouldUsePinyin || string.IsNullOrEmpty(characters))
|
||||||
{
|
|
||||||
if (!PinyinCache.ContainsKey(characters))
|
|
||||||
{
|
|
||||||
|
|
||||||
var allPinyins = new List<string[]>();
|
|
||||||
foreach (var c in characters)
|
|
||||||
{
|
|
||||||
var pinyins = PinyinHelper.toHanyuPinyinStringArray(c, Format);
|
|
||||||
if (pinyins != null)
|
|
||||||
{
|
|
||||||
var r = pinyins.Distinct().ToArray();
|
|
||||||
allPinyins.Add(r);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var r = new[] { c.ToString() };
|
|
||||||
allPinyins.Add(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var combination = allPinyins.Aggregate(Combination).Select(c => c.Split(';')).ToArray();
|
|
||||||
PinyinCache[characters] = combination;
|
|
||||||
return combination;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return PinyinCache[characters];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return Empty2DStringArray;
|
return Empty2DStringArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!PinyinCache.ContainsKey(characters))
|
||||||
|
{
|
||||||
|
var allPinyins = new List<string[]>();
|
||||||
|
foreach (var c in characters)
|
||||||
|
{
|
||||||
|
var pinyins = PinyinHelper.toHanyuPinyinStringArray(c, Format);
|
||||||
|
if (pinyins != null)
|
||||||
|
{
|
||||||
|
var r = pinyins.Distinct().ToArray();
|
||||||
|
allPinyins.Add(r);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var r = new[] { c.ToString() };
|
||||||
|
allPinyins.Add(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var combination = allPinyins.Aggregate(Combination).Select(c => c.Split(';')).ToArray();
|
||||||
|
PinyinCache[characters] = combination;
|
||||||
|
return combination;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PinyinCache[characters];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Acronym(string[] pinyin)
|
public string Acronym(string[] pinyin)
|
||||||
{
|
{
|
||||||
var acronym = string.Join("", pinyin.Select(p => p[0]));
|
var acronym = string.Join("", pinyin.Select(p => p[0]));
|
||||||
return acronym;
|
return acronym;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ContainsChinese(string word)
|
public bool ContainsChinese(string word)
|
||||||
{
|
{
|
||||||
if (!_settings.ShouldUsePinyin)
|
if (!_settings.ShouldUsePinyin)
|
||||||
{
|
{
|
||||||
|
|
@ -128,7 +171,7 @@ namespace Wox.Infrastructure
|
||||||
return chinese;
|
return chinese;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string[] Combination(string[] array1, string[] array2)
|
private string[] Combination(string[] array1, string[] array2)
|
||||||
{
|
{
|
||||||
if (!_settings.ShouldUsePinyin)
|
if (!_settings.ShouldUsePinyin)
|
||||||
{
|
{
|
||||||
|
|
@ -142,7 +185,5 @@ namespace Wox.Infrastructure
|
||||||
).ToArray();
|
).ToArray();
|
||||||
return combination;
|
return combination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ namespace Wox.Infrastructure
|
||||||
|
|
||||||
public static FuzzyMatcher Create(string query)
|
public static FuzzyMatcher Create(string query)
|
||||||
{
|
{
|
||||||
return new FuzzyMatcher(query, StringMatcher.DefaultMatchOption);
|
return new FuzzyMatcher(query, new MatchOption());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FuzzyMatcher Create(string query, MatchOption opt)
|
public static FuzzyMatcher Create(string query, MatchOption opt)
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Wox.Infrastructure
|
||||||
|
|
||||||
public MatchResult Evaluate(string str)
|
public MatchResult Evaluate(string str)
|
||||||
{
|
{
|
||||||
return StringMatcher.FuzzySearch(query, str, opt);
|
return StringMatcher.Instance.FuzzyMatch(query, str, opt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ namespace Wox.Infrastructure
|
||||||
|
|
||||||
public static void ValidateDataDirectory(string bundledDataDirectory, string dataDirectory)
|
public static void ValidateDataDirectory(string bundledDataDirectory, string dataDirectory)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!Directory.Exists(dataDirectory))
|
if (!Directory.Exists(dataDirectory))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(dataDirectory);
|
Directory.CreateDirectory(dataDirectory);
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,16 @@ namespace Wox.Infrastructure.Http
|
||||||
{
|
{
|
||||||
private const string UserAgent = @"Mozilla/5.0 (Trident/7.0; rv:11.0) like Gecko";
|
private const string UserAgent = @"Mozilla/5.0 (Trident/7.0; rv:11.0) like Gecko";
|
||||||
|
|
||||||
|
static Http()
|
||||||
|
{
|
||||||
|
// need to be added so it would work on a win10 machine
|
||||||
|
ServicePointManager.Expect100Continue = true;
|
||||||
|
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls
|
||||||
|
| SecurityProtocolType.Tls11
|
||||||
|
| SecurityProtocolType.Tls12
|
||||||
|
| SecurityProtocolType.Ssl3;
|
||||||
|
}
|
||||||
|
|
||||||
public static HttpProxy Proxy { private get; set; }
|
public static HttpProxy Proxy { private get; set; }
|
||||||
public static IWebProxy WebProxy()
|
public static IWebProxy WebProxy()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,19 @@ namespace Wox.Infrastructure.Image
|
||||||
var contains = _data.ContainsKey(key);
|
var contains = _data.ContainsKey(key);
|
||||||
return contains;
|
return contains;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int CacheSize()
|
||||||
|
{
|
||||||
|
return _data.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// return the number of unique images in the cache (by reference not by checking images content)
|
||||||
|
/// </summary>
|
||||||
|
public int UniqueImagesInCache()
|
||||||
|
{
|
||||||
|
return _data.Values.Distinct().Count();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
49
Wox.Infrastructure/Image/ImageHashGenerator.cs
Normal file
49
Wox.Infrastructure/Image/ImageHashGenerator.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
|
namespace Wox.Infrastructure.Image
|
||||||
|
{
|
||||||
|
public interface IImageHashGenerator
|
||||||
|
{
|
||||||
|
string GetHashFromImage(ImageSource image);
|
||||||
|
}
|
||||||
|
public class ImageHashGenerator : IImageHashGenerator
|
||||||
|
{
|
||||||
|
public string GetHashFromImage(ImageSource imageSource)
|
||||||
|
{
|
||||||
|
if (!(imageSource is BitmapSource image))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var outStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
// PngBitmapEncoder enc2 = new PngBitmapEncoder();
|
||||||
|
// enc2.Frames.Add(BitmapFrame.Create(tt));
|
||||||
|
|
||||||
|
var enc = new JpegBitmapEncoder();
|
||||||
|
var bitmapFrame = BitmapFrame.Create(image);
|
||||||
|
bitmapFrame.Freeze();
|
||||||
|
enc.Frames.Add(bitmapFrame);
|
||||||
|
enc.Save(outStream);
|
||||||
|
var byteArray = outStream.GetBuffer();
|
||||||
|
using (var sha1 = new SHA1CryptoServiceProvider())
|
||||||
|
{
|
||||||
|
var hash = Convert.ToBase64String(sha1.ComputeHash(byteArray));
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,8 @@ namespace Wox.Infrastructure.Image
|
||||||
{
|
{
|
||||||
private static readonly ImageCache ImageCache = new ImageCache();
|
private static readonly ImageCache ImageCache = new ImageCache();
|
||||||
private static BinaryStorage<ConcurrentDictionary<string, int>> _storage;
|
private static BinaryStorage<ConcurrentDictionary<string, int>> _storage;
|
||||||
|
private static readonly ConcurrentDictionary<string, string> GuidToKey = new ConcurrentDictionary<string, string>();
|
||||||
|
private static IImageHashGenerator _hashGenerator;
|
||||||
|
|
||||||
|
|
||||||
private static readonly string[] ImageExtensions =
|
private static readonly string[] ImageExtensions =
|
||||||
|
|
@ -30,7 +32,8 @@ namespace Wox.Infrastructure.Image
|
||||||
|
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
_storage = new BinaryStorage<ConcurrentDictionary<string, int>> ("Image");
|
_storage = new BinaryStorage<ConcurrentDictionary<string, int>>("Image");
|
||||||
|
_hashGenerator = new ImageHashGenerator();
|
||||||
ImageCache.Usage = _storage.TryLoad(new ConcurrentDictionary<string, int>());
|
ImageCache.Usage = _storage.TryLoad(new ConcurrentDictionary<string, int>());
|
||||||
|
|
||||||
foreach (var icon in new[] { Constant.DefaultIcon, Constant.ErrorIcon })
|
foreach (var icon in new[] { Constant.DefaultIcon, Constant.ErrorIcon })
|
||||||
|
|
@ -43,16 +46,12 @@ namespace Wox.Infrastructure.Image
|
||||||
{
|
{
|
||||||
Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () =>
|
Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () =>
|
||||||
{
|
{
|
||||||
ImageCache.Usage.AsParallel().Where(i => !ImageCache.ContainsKey(i.Key)).ForAll(i =>
|
ImageCache.Usage.AsParallel().ForAll(x =>
|
||||||
{
|
{
|
||||||
var img = Load(i.Key);
|
Load(x.Key);
|
||||||
if (img != null)
|
|
||||||
{
|
|
||||||
ImageCache[i.Key] = img;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Log.Info($"|ImageLoader.Initialize|Number of preload images is <{ImageCache.Usage.Count}>");
|
Log.Info($"|ImageLoader.Initialize|Number of preload images is <{ImageCache.Usage.Count}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,31 +60,56 @@ namespace Wox.Infrastructure.Image
|
||||||
ImageCache.Cleanup();
|
ImageCache.Cleanup();
|
||||||
_storage.Save(ImageCache.Usage);
|
_storage.Save(ImageCache.Usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageSource Load(string path, bool loadFullImage = false)
|
private class ImageResult
|
||||||
|
{
|
||||||
|
public ImageResult(ImageSource imageSource, ImageType imageType)
|
||||||
|
{
|
||||||
|
ImageSource = imageSource;
|
||||||
|
ImageType = imageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageType ImageType { get; }
|
||||||
|
public ImageSource ImageSource { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum ImageType
|
||||||
|
{
|
||||||
|
File,
|
||||||
|
Folder,
|
||||||
|
Data,
|
||||||
|
ImageFile,
|
||||||
|
Error,
|
||||||
|
Cache
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImageResult LoadInternal(string path, bool loadFullImage = false)
|
||||||
{
|
{
|
||||||
ImageSource image;
|
ImageSource image;
|
||||||
|
ImageType type = ImageType.Error;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(path))
|
if (string.IsNullOrEmpty(path))
|
||||||
{
|
{
|
||||||
return ImageCache[Constant.ErrorIcon];
|
return new ImageResult(ImageCache[Constant.ErrorIcon], ImageType.Error);
|
||||||
}
|
}
|
||||||
if (ImageCache.ContainsKey(path))
|
if (ImageCache.ContainsKey(path))
|
||||||
{
|
{
|
||||||
return ImageCache[path];
|
return new ImageResult(ImageCache[path], ImageType.Cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
|
if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new BitmapImage(new Uri(path));
|
var imageSource = new BitmapImage(new Uri(path));
|
||||||
|
imageSource.Freeze();
|
||||||
|
return new ImageResult(imageSource, ImageType.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Path.IsPathRooted(path))
|
if (!Path.IsPathRooted(path))
|
||||||
{
|
{
|
||||||
path = Path.Combine(Constant.ProgramDirectory, "Images", Path.GetFileName(path));
|
path = Path.Combine(Constant.ProgramDirectory, "Images", Path.GetFileName(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Directory.Exists(path))
|
if (Directory.Exists(path))
|
||||||
{
|
{
|
||||||
/* Directories can also have thumbnails instead of shell icons.
|
/* Directories can also have thumbnails instead of shell icons.
|
||||||
|
|
@ -94,14 +118,17 @@ namespace Wox.Infrastructure.Image
|
||||||
* Wox responsibility.
|
* Wox responsibility.
|
||||||
* - Solution: just load the icon
|
* - Solution: just load the icon
|
||||||
*/
|
*/
|
||||||
|
type = ImageType.Folder;
|
||||||
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize,
|
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize,
|
||||||
Constant.ThumbnailSize, ThumbnailOptions.IconOnly);
|
Constant.ThumbnailSize, ThumbnailOptions.IconOnly);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (File.Exists(path))
|
else if (File.Exists(path))
|
||||||
{
|
{
|
||||||
var extension = Path.GetExtension(path).ToLower();
|
var extension = Path.GetExtension(path).ToLower();
|
||||||
if (ImageExtensions.Contains(extension))
|
if (ImageExtensions.Contains(extension))
|
||||||
{
|
{
|
||||||
|
type = ImageType.ImageFile;
|
||||||
if (loadFullImage)
|
if (loadFullImage)
|
||||||
{
|
{
|
||||||
image = LoadFullImage(path);
|
image = LoadFullImage(path);
|
||||||
|
|
@ -119,6 +146,7 @@ namespace Wox.Infrastructure.Image
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
type = ImageType.File;
|
||||||
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize,
|
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize,
|
||||||
Constant.ThumbnailSize, ThumbnailOptions.None);
|
Constant.ThumbnailSize, ThumbnailOptions.None);
|
||||||
}
|
}
|
||||||
|
|
@ -128,17 +156,50 @@ namespace Wox.Infrastructure.Image
|
||||||
image = ImageCache[Constant.ErrorIcon];
|
image = ImageCache[Constant.ErrorIcon];
|
||||||
path = Constant.ErrorIcon;
|
path = Constant.ErrorIcon;
|
||||||
}
|
}
|
||||||
ImageCache[path] = image;
|
|
||||||
image.Freeze();
|
if (type != ImageType.Error)
|
||||||
|
{
|
||||||
|
image.Freeze();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path}", e);
|
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path}", e);
|
||||||
|
type = ImageType.Error;
|
||||||
image = ImageCache[Constant.ErrorIcon];
|
image = ImageCache[Constant.ErrorIcon];
|
||||||
ImageCache[path] = image;
|
ImageCache[path] = image;
|
||||||
}
|
}
|
||||||
return image;
|
return new ImageResult(image, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool EnableImageHash = true;
|
||||||
|
|
||||||
|
public static ImageSource Load(string path, bool loadFullImage = false)
|
||||||
|
{
|
||||||
|
var imageResult = LoadInternal(path, loadFullImage);
|
||||||
|
|
||||||
|
var img = imageResult.ImageSource;
|
||||||
|
if (imageResult.ImageType != ImageType.Error && imageResult.ImageType != ImageType.Cache)
|
||||||
|
{ // we need to get image hash
|
||||||
|
string hash = EnableImageHash ? _hashGenerator.GetHashFromImage(img) : null;
|
||||||
|
if (hash != null)
|
||||||
|
{
|
||||||
|
if (GuidToKey.TryGetValue(hash, out string key))
|
||||||
|
{ // image already exists
|
||||||
|
img = ImageCache[key];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // new guid
|
||||||
|
GuidToKey[hash] = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update cache
|
||||||
|
ImageCache[path] = img;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BitmapImage LoadFullImage(string path)
|
private static BitmapImage LoadFullImage(string path)
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,6 @@ namespace Wox.Infrastructure.Image
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
return Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
|
return Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
||||||
|
|
@ -11,18 +11,20 @@ namespace Wox.Infrastructure.Logger
|
||||||
{
|
{
|
||||||
public const string DirectoryName = "Logs";
|
public const string DirectoryName = "Logs";
|
||||||
|
|
||||||
|
public static string CurrentLogDirectory { get; }
|
||||||
|
|
||||||
static Log()
|
static Log()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(Constant.DataDirectory, DirectoryName, Constant.Version);
|
CurrentLogDirectory = Path.Combine(Constant.DataDirectory, DirectoryName, Constant.Version);
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(CurrentLogDirectory))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(CurrentLogDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
var configuration = new LoggingConfiguration();
|
var configuration = new LoggingConfiguration();
|
||||||
var target = new FileTarget();
|
var target = new FileTarget();
|
||||||
configuration.AddTarget("file", target);
|
configuration.AddTarget("file", target);
|
||||||
target.FileName = path.Replace(@"\", "/") + "/${shortdate}.txt";
|
target.FileName = CurrentLogDirectory.Replace(@"\", "/") + "/${shortdate}.txt";
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
var rule = new LoggingRule("*", LogLevel.Debug, target);
|
var rule = new LoggingRule("*", LogLevel.Debug, target);
|
||||||
#else
|
#else
|
||||||
|
|
@ -47,8 +49,62 @@ namespace Wox.Infrastructure.Logger
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <param name="message">example: "|prefix|unprefixed" </param>
|
|
||||||
public static void Error(string message)
|
|
||||||
|
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public static void Exception(string className, string message, System.Exception exception, [CallerMemberName] string methodName = "")
|
||||||
|
{
|
||||||
|
var classNameWithMethod = CheckClassAndMessageAndReturnFullClassWithMethod(className, message, methodName);
|
||||||
|
|
||||||
|
ExceptionInternal(classNameWithMethod, message, exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string CheckClassAndMessageAndReturnFullClassWithMethod(string className, string message,
|
||||||
|
string methodName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(className))
|
||||||
|
{
|
||||||
|
LogFaultyFormat($"Fail to specify a class name during logging of message: {message ?? "no message entered"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(message))
|
||||||
|
{
|
||||||
|
// todo: not sure we really need that
|
||||||
|
LogFaultyFormat($"Fail to specify a message during logging");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(methodName))
|
||||||
|
{
|
||||||
|
return className + "." + methodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ExceptionInternal(string classAndMethod, string message, System.Exception e)
|
||||||
|
{
|
||||||
|
var logger = LogManager.GetLogger(classAndMethod);
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine($"ERROR|{message}");
|
||||||
|
|
||||||
|
logger.Error("-------------------------- Begin exception --------------------------");
|
||||||
|
logger.Error(message);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
logger.Error($"Exception full name:\n <{e.GetType().FullName}>");
|
||||||
|
logger.Error($"Exception message:\n <{e.Message}>");
|
||||||
|
logger.Error($"Exception stack trace:\n <{e.StackTrace}>");
|
||||||
|
logger.Error($"Exception source:\n <{e.Source}>");
|
||||||
|
logger.Error($"Exception target site:\n <{e.TargetSite}>");
|
||||||
|
logger.Error($"Exception HResult:\n <{e.HResult}>");
|
||||||
|
e = e.InnerException;
|
||||||
|
} while (e != null);
|
||||||
|
|
||||||
|
logger.Error("-------------------------- End exception --------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LogInternal(string message, LogLevel level)
|
||||||
{
|
{
|
||||||
if (FormatValid(message))
|
if (FormatValid(message))
|
||||||
{
|
{
|
||||||
|
|
@ -57,8 +113,8 @@ namespace Wox.Infrastructure.Logger
|
||||||
var unprefixed = parts[2];
|
var unprefixed = parts[2];
|
||||||
var logger = LogManager.GetLogger(prefix);
|
var logger = LogManager.GetLogger(prefix);
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"ERROR|{message}");
|
System.Diagnostics.Debug.WriteLine($"{level.Name}|{message}");
|
||||||
logger.Error(unprefixed);
|
logger.Log(level, unprefixed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -78,25 +134,7 @@ namespace Wox.Infrastructure.Logger
|
||||||
var parts = message.Split('|');
|
var parts = message.Split('|');
|
||||||
var prefix = parts[1];
|
var prefix = parts[1];
|
||||||
var unprefixed = parts[2];
|
var unprefixed = parts[2];
|
||||||
var logger = LogManager.GetLogger(prefix);
|
ExceptionInternal(prefix, unprefixed, e);
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"ERROR|{message}");
|
|
||||||
|
|
||||||
logger.Error("-------------------------- Begin exception --------------------------");
|
|
||||||
logger.Error(unprefixed);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
logger.Error($"Exception fulle name:\n <{e.GetType().FullName}>");
|
|
||||||
logger.Error($"Exception message:\n <{e.Message}>");
|
|
||||||
logger.Error($"Exception stack trace:\n <{e.StackTrace}>");
|
|
||||||
logger.Error($"Exception source:\n <{e.Source}>");
|
|
||||||
logger.Error($"Exception target site:\n <{e.TargetSite}>");
|
|
||||||
logger.Error($"Exception HResult:\n <{e.HResult}>");
|
|
||||||
e = e.InnerException;
|
|
||||||
} while (e != null);
|
|
||||||
|
|
||||||
logger.Error("-------------------------- End exception --------------------------");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -104,62 +142,59 @@ namespace Wox.Infrastructure.Logger
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <param name="message">example: "|prefix|unprefixed" </param>
|
||||||
|
public static void Error(string message)
|
||||||
|
{
|
||||||
|
LogInternal(message, LogLevel.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Error(string className, string message, [CallerMemberName] string methodName = "")
|
||||||
|
{
|
||||||
|
LogInternal(LogLevel.Error, className, message, methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LogInternal(LogLevel level, string className, string message, [CallerMemberName] string methodName = "")
|
||||||
|
{
|
||||||
|
var classNameWithMethod = CheckClassAndMessageAndReturnFullClassWithMethod(className, message, methodName);
|
||||||
|
|
||||||
|
var logger = LogManager.GetLogger(classNameWithMethod);
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine($"{level.Name}|{message}");
|
||||||
|
logger.Log(level, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Debug(string className, string message, [CallerMemberName] string methodName = "")
|
||||||
|
{
|
||||||
|
LogInternal(LogLevel.Debug, className, message, methodName);
|
||||||
|
}
|
||||||
|
|
||||||
/// <param name="message">example: "|prefix|unprefixed" </param>
|
/// <param name="message">example: "|prefix|unprefixed" </param>
|
||||||
public static void Debug(string message)
|
public static void Debug(string message)
|
||||||
{
|
{
|
||||||
if (FormatValid(message))
|
LogInternal(message, LogLevel.Debug);
|
||||||
{
|
}
|
||||||
var parts = message.Split('|');
|
|
||||||
var prefix = parts[1];
|
|
||||||
var unprefixed = parts[2];
|
|
||||||
var logger = LogManager.GetLogger(prefix);
|
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"DEBUG|{message}");
|
public static void Info(string className, string message, [CallerMemberName] string methodName = "")
|
||||||
logger.Debug(unprefixed);
|
{
|
||||||
}
|
LogInternal(LogLevel.Info, className, message, methodName);
|
||||||
else
|
|
||||||
{
|
|
||||||
LogFaultyFormat(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <param name="message">example: "|prefix|unprefixed" </param>
|
/// <param name="message">example: "|prefix|unprefixed" </param>
|
||||||
public static void Info(string message)
|
public static void Info(string message)
|
||||||
{
|
{
|
||||||
if (FormatValid(message))
|
LogInternal(message, LogLevel.Info);
|
||||||
{
|
}
|
||||||
var parts = message.Split('|');
|
|
||||||
var prefix = parts[1];
|
|
||||||
var unprefixed = parts[2];
|
|
||||||
var logger = LogManager.GetLogger(prefix);
|
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"INFO|{message}");
|
public static void Warn(string className, string message, [CallerMemberName] string methodName = "")
|
||||||
logger.Info(unprefixed);
|
{
|
||||||
}
|
LogInternal(LogLevel.Warn, className, message, methodName);
|
||||||
else
|
|
||||||
{
|
|
||||||
LogFaultyFormat(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <param name="message">example: "|prefix|unprefixed" </param>
|
/// <param name="message">example: "|prefix|unprefixed" </param>
|
||||||
public static void Warn(string message)
|
public static void Warn(string message)
|
||||||
{
|
{
|
||||||
if (FormatValid(message))
|
LogInternal(message, LogLevel.Warn);
|
||||||
{
|
|
||||||
var parts = message.Split('|');
|
|
||||||
var prefix = parts[1];
|
|
||||||
var unprefixed = parts[2];
|
|
||||||
var logger = LogManager.GetLogger(prefix);
|
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"WARN|{message}");
|
|
||||||
logger.Warn(unprefixed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogFaultyFormat(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,108 +1,220 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using static Wox.Infrastructure.StringMatcher;
|
||||||
using Wox.Infrastructure.Logger;
|
|
||||||
using Wox.Infrastructure.UserSettings;
|
|
||||||
|
|
||||||
namespace Wox.Infrastructure
|
namespace Wox.Infrastructure
|
||||||
{
|
{
|
||||||
public static class StringMatcher
|
public class StringMatcher
|
||||||
{
|
{
|
||||||
public static MatchOption DefaultMatchOption = new MatchOption();
|
private readonly MatchOption _defaultMatchOption = new MatchOption();
|
||||||
|
|
||||||
public static string UserSettingSearchPrecision { get; set; }
|
public SearchPrecisionScore UserSettingSearchPrecision { get; set; }
|
||||||
|
|
||||||
|
private readonly IAlphabet _alphabet;
|
||||||
|
|
||||||
|
public StringMatcher(IAlphabet alphabet = null)
|
||||||
|
{
|
||||||
|
_alphabet = alphabet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StringMatcher Instance { get; internal set; }
|
||||||
|
|
||||||
[Obsolete("This method is obsolete and should not be used. Please use the static function StringMatcher.FuzzySearch")]
|
[Obsolete("This method is obsolete and should not be used. Please use the static function StringMatcher.FuzzySearch")]
|
||||||
public static int Score(string source, string target)
|
public static int Score(string source, string target)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(target))
|
return FuzzySearch(target, source).Score;
|
||||||
{
|
|
||||||
return FuzzySearch(target, source, DefaultMatchOption).Score;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("This method is obsolete and should not be used. Please use the static function StringMatcher.FuzzySearch")]
|
[Obsolete("This method is obsolete and should not be used. Please use the static function StringMatcher.FuzzySearch")]
|
||||||
public static bool IsMatch(string source, string target)
|
public static bool IsMatch(string source, string target)
|
||||||
{
|
{
|
||||||
return FuzzySearch(target, source, DefaultMatchOption).Score > 0;
|
return Score(source, target) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MatchResult FuzzySearch(string query, string stringToCompare)
|
public static MatchResult FuzzySearch(string query, string stringToCompare)
|
||||||
{
|
{
|
||||||
return FuzzySearch(query, stringToCompare, DefaultMatchOption);
|
return Instance.FuzzyMatch(query, stringToCompare);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MatchResult FuzzyMatch(string query, string stringToCompare)
|
||||||
|
{
|
||||||
|
return FuzzyMatch(query, stringToCompare, _defaultMatchOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// refer to https://github.com/mattyork/fuzzy
|
/// Current method:
|
||||||
|
/// Character matching + substring matching;
|
||||||
|
/// 1. Query search string is split into substrings, separator is whitespace.
|
||||||
|
/// 2. Check each query substring's characters against full compare string,
|
||||||
|
/// 3. if a character in the substring is matched, loop back to verify the previous character.
|
||||||
|
/// 4. If previous character also matches, and is the start of the substring, update list.
|
||||||
|
/// 5. Once the previous character is verified, move on to the next character in the query substring.
|
||||||
|
/// 6. Move onto the next substring's characters until all substrings are checked.
|
||||||
|
/// 7. Consider success and move onto scoring if every char or substring without whitespaces matched
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static MatchResult FuzzySearch(string query, string stringToCompare, MatchOption opt)
|
public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption opt)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(stringToCompare) || string.IsNullOrEmpty(query)) return new MatchResult { Success = false };
|
if (string.IsNullOrEmpty(stringToCompare) || string.IsNullOrEmpty(query)) return new MatchResult (false, UserSettingSearchPrecision);
|
||||||
|
|
||||||
query = query.Trim();
|
query = query.Trim();
|
||||||
|
|
||||||
var len = stringToCompare.Length;
|
if (_alphabet != null)
|
||||||
var compareString = opt.IgnoreCase ? stringToCompare.ToLower() : stringToCompare;
|
{
|
||||||
var pattern = opt.IgnoreCase ? query.ToLower() : query;
|
query = _alphabet.Translate(query);
|
||||||
|
stringToCompare = _alphabet.Translate(stringToCompare);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fullStringToCompareWithoutCase = opt.IgnoreCase ? stringToCompare.ToLower() : stringToCompare;
|
||||||
|
|
||||||
|
var queryWithoutCase = opt.IgnoreCase ? query.ToLower() : query;
|
||||||
|
|
||||||
|
var querySubstrings = queryWithoutCase.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
int currentQuerySubstringIndex = 0;
|
||||||
|
var currentQuerySubstring = querySubstrings[currentQuerySubstringIndex];
|
||||||
|
var currentQuerySubstringCharacterIndex = 0;
|
||||||
|
|
||||||
var sb = new StringBuilder(stringToCompare.Length + (query.Length * (opt.Prefix.Length + opt.Suffix.Length)));
|
|
||||||
var patternIdx = 0;
|
|
||||||
var firstMatchIndex = -1;
|
var firstMatchIndex = -1;
|
||||||
|
var firstMatchIndexInWord = -1;
|
||||||
var lastMatchIndex = 0;
|
var lastMatchIndex = 0;
|
||||||
char ch;
|
bool allQuerySubstringsMatched = false;
|
||||||
for (var idx = 0; idx < len; idx++)
|
bool matchFoundInPreviousLoop = false;
|
||||||
|
bool allSubstringsContainedInCompareString = true;
|
||||||
|
|
||||||
|
var indexList = new List<int>();
|
||||||
|
|
||||||
|
for (var compareStringIndex = 0; compareStringIndex < fullStringToCompareWithoutCase.Length; compareStringIndex++)
|
||||||
{
|
{
|
||||||
ch = stringToCompare[idx];
|
if (fullStringToCompareWithoutCase[compareStringIndex] != currentQuerySubstring[currentQuerySubstringCharacterIndex])
|
||||||
if (compareString[idx] == pattern[patternIdx])
|
|
||||||
{
|
{
|
||||||
if (firstMatchIndex < 0)
|
matchFoundInPreviousLoop = false;
|
||||||
firstMatchIndex = idx;
|
continue;
|
||||||
lastMatchIndex = idx + 1;
|
|
||||||
|
|
||||||
sb.Append(opt.Prefix + ch + opt.Suffix);
|
|
||||||
patternIdx += 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.Append(ch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// match success, append remain char
|
if (firstMatchIndex < 0)
|
||||||
if (patternIdx == pattern.Length && (idx + 1) != compareString.Length)
|
|
||||||
{
|
{
|
||||||
sb.Append(stringToCompare.Substring(idx + 1));
|
// first matched char will become the start of the compared string
|
||||||
break;
|
firstMatchIndex = compareStringIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentQuerySubstringCharacterIndex == 0)
|
||||||
|
{
|
||||||
|
// first letter of current word
|
||||||
|
matchFoundInPreviousLoop = true;
|
||||||
|
firstMatchIndexInWord = compareStringIndex;
|
||||||
|
}
|
||||||
|
else if (!matchFoundInPreviousLoop)
|
||||||
|
{
|
||||||
|
// we want to verify that there is not a better match if this is not a full word
|
||||||
|
// in order to do so we need to verify all previous chars are part of the pattern
|
||||||
|
var startIndexToVerify = compareStringIndex - currentQuerySubstringCharacterIndex;
|
||||||
|
|
||||||
|
if (AllPreviousCharsMatched(startIndexToVerify, currentQuerySubstringCharacterIndex, fullStringToCompareWithoutCase, currentQuerySubstring))
|
||||||
|
{
|
||||||
|
matchFoundInPreviousLoop = true;
|
||||||
|
|
||||||
|
// if it's the beginning character of the first query substring that is matched then we need to update start index
|
||||||
|
firstMatchIndex = currentQuerySubstringIndex == 0 ? startIndexToVerify : firstMatchIndex;
|
||||||
|
|
||||||
|
indexList = GetUpdatedIndexList(startIndexToVerify, currentQuerySubstringCharacterIndex, firstMatchIndexInWord, indexList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastMatchIndex = compareStringIndex + 1;
|
||||||
|
indexList.Add(compareStringIndex);
|
||||||
|
|
||||||
|
currentQuerySubstringCharacterIndex++;
|
||||||
|
|
||||||
|
// if finished looping through every character in the current substring
|
||||||
|
if (currentQuerySubstringCharacterIndex == currentQuerySubstring.Length)
|
||||||
|
{
|
||||||
|
// if any of the substrings was not matched then consider as all are not matched
|
||||||
|
allSubstringsContainedInCompareString = matchFoundInPreviousLoop && allSubstringsContainedInCompareString;
|
||||||
|
|
||||||
|
currentQuerySubstringIndex++;
|
||||||
|
|
||||||
|
allQuerySubstringsMatched = AllQuerySubstringsMatched(currentQuerySubstringIndex, querySubstrings.Length);
|
||||||
|
if (allQuerySubstringsMatched)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// otherwise move to the next query substring
|
||||||
|
currentQuerySubstring = querySubstrings[currentQuerySubstringIndex];
|
||||||
|
currentQuerySubstringCharacterIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return rendered string if we have a match for every char
|
// proceed to calculate score if every char or substring without whitespaces matched
|
||||||
if (patternIdx == pattern.Length)
|
if (allQuerySubstringsMatched)
|
||||||
{
|
{
|
||||||
return new MatchResult
|
var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex, lastMatchIndex - firstMatchIndex, allSubstringsContainedInCompareString);
|
||||||
{
|
|
||||||
Success = true,
|
return new MatchResult(true, UserSettingSearchPrecision, indexList, score);
|
||||||
Value = sb.ToString(),
|
|
||||||
Score = CalScore(query, stringToCompare, firstMatchIndex, lastMatchIndex - firstMatchIndex)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MatchResult { Success = false };
|
return new MatchResult (false, UserSettingSearchPrecision);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int CalScore(string query, string stringToCompare, int firstIndex, int matchLen)
|
private static bool AllPreviousCharsMatched(int startIndexToVerify, int currentQuerySubstringCharacterIndex,
|
||||||
|
string fullStringToCompareWithoutCase, string currentQuerySubstring)
|
||||||
{
|
{
|
||||||
//a match found near the beginning of a string is scored more than a match found near the end
|
var allMatch = true;
|
||||||
//a match is scored more if the characters in the patterns are closer to each other, while the score is lower if they are more spread out
|
for (int indexToCheck = 0; indexToCheck < currentQuerySubstringCharacterIndex; indexToCheck++)
|
||||||
|
{
|
||||||
|
if (fullStringToCompareWithoutCase[startIndexToVerify + indexToCheck] !=
|
||||||
|
currentQuerySubstring[indexToCheck])
|
||||||
|
{
|
||||||
|
allMatch = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<int> GetUpdatedIndexList(int startIndexToVerify, int currentQuerySubstringCharacterIndex, int firstMatchIndexInWord, List<int> indexList)
|
||||||
|
{
|
||||||
|
var updatedList = new List<int>();
|
||||||
|
|
||||||
|
indexList.RemoveAll(x => x >= firstMatchIndexInWord);
|
||||||
|
|
||||||
|
updatedList.AddRange(indexList);
|
||||||
|
|
||||||
|
for (int indexToCheck = 0; indexToCheck < currentQuerySubstringCharacterIndex; indexToCheck++)
|
||||||
|
{
|
||||||
|
updatedList.Add(startIndexToVerify + indexToCheck);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool AllQuerySubstringsMatched(int currentQuerySubstringIndex, int querySubstringsLength)
|
||||||
|
{
|
||||||
|
return currentQuerySubstringIndex >= querySubstringsLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int CalculateSearchScore(string query, string stringToCompare, int firstIndex, int matchLen, bool allSubstringsContainedInCompareString)
|
||||||
|
{
|
||||||
|
// A match found near the beginning of a string is scored more than a match found near the end
|
||||||
|
// A match is scored more if the characters in the patterns are closer to each other,
|
||||||
|
// while the score is lower if they are more spread out
|
||||||
var score = 100 * (query.Length + 1) / ((1 + firstIndex) + (matchLen + 1));
|
var score = 100 * (query.Length + 1) / ((1 + firstIndex) + (matchLen + 1));
|
||||||
//a match with less characters assigning more weights
|
|
||||||
|
// A match with less characters assigning more weights
|
||||||
if (stringToCompare.Length - query.Length < 5)
|
if (stringToCompare.Length - query.Length < 5)
|
||||||
|
{
|
||||||
score += 20;
|
score += 20;
|
||||||
|
}
|
||||||
else if (stringToCompare.Length - query.Length < 10)
|
else if (stringToCompare.Length - query.Length < 10)
|
||||||
|
{
|
||||||
score += 10;
|
score += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allSubstringsContainedInCompareString)
|
||||||
|
{
|
||||||
|
int count = query.Count(c => !char.IsWhiteSpace(c));
|
||||||
|
int factor = count < 4 ? 10 : 5;
|
||||||
|
score += factor * count;
|
||||||
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
@ -113,77 +225,83 @@ namespace Wox.Infrastructure
|
||||||
Low = 20,
|
Low = 20,
|
||||||
None = 0
|
None = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsSearchPrecisionScoreMet(this MatchResult matchResult)
|
|
||||||
{
|
|
||||||
var precisionScore = (SearchPrecisionScore)Enum.Parse(typeof(SearchPrecisionScore),
|
|
||||||
UserSettingSearchPrecision ?? SearchPrecisionScore.Regular.ToString());
|
|
||||||
return matchResult.Score >= (int)precisionScore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int ScoreAfterSearchPrecisionFilter(this MatchResult matchResult)
|
|
||||||
{
|
|
||||||
return matchResult.IsSearchPrecisionScoreMet() ? matchResult.Score : 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int ScoreForPinyin(string source, string target)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(target))
|
|
||||||
{
|
|
||||||
if (Alphabet.ContainsChinese(source))
|
|
||||||
{
|
|
||||||
var combination = Alphabet.PinyinComination(source);
|
|
||||||
var pinyinScore = combination
|
|
||||||
.Select(pinyin => FuzzySearch(target, string.Join("", pinyin)).Score)
|
|
||||||
.Max();
|
|
||||||
var acronymScore = combination.Select(Alphabet.Acronym)
|
|
||||||
.Select(pinyin => FuzzySearch(target, pinyin).Score)
|
|
||||||
.Max();
|
|
||||||
var score = Math.Max(pinyinScore, acronymScore);
|
|
||||||
return score;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MatchResult
|
public class MatchResult
|
||||||
{
|
{
|
||||||
|
public MatchResult(bool success, SearchPrecisionScore searchPrecision)
|
||||||
|
{
|
||||||
|
Success = success;
|
||||||
|
SearchPrecision = searchPrecision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MatchResult(bool success, SearchPrecisionScore searchPrecision, List<int> matchData, int rawScore)
|
||||||
|
{
|
||||||
|
Success = success;
|
||||||
|
SearchPrecision = searchPrecision;
|
||||||
|
MatchData = matchData;
|
||||||
|
RawScore = rawScore;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Success { get; set; }
|
public bool Success { get; set; }
|
||||||
public int Score { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// highlight string
|
/// The final score of the match result with search precision filters applied.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Value { get; set; }
|
public int Score { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The raw calculated search score without any search precision filtering applied.
|
||||||
|
/// </summary>
|
||||||
|
private int _rawScore;
|
||||||
|
|
||||||
|
public int RawScore
|
||||||
|
{
|
||||||
|
get { return _rawScore; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_rawScore = value;
|
||||||
|
Score = ScoreAfterSearchPrecisionFilter(_rawScore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Matched data to highlight.
|
||||||
|
/// </summary>
|
||||||
|
public List<int> MatchData { get; set; }
|
||||||
|
|
||||||
|
public SearchPrecisionScore SearchPrecision { get; set; }
|
||||||
|
|
||||||
|
public bool IsSearchPrecisionScoreMet()
|
||||||
|
{
|
||||||
|
return IsSearchPrecisionScoreMet(_rawScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsSearchPrecisionScoreMet(int rawScore)
|
||||||
|
{
|
||||||
|
return rawScore >= (int)SearchPrecision;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ScoreAfterSearchPrecisionFilter(int rawScore)
|
||||||
|
{
|
||||||
|
return IsSearchPrecisionScoreMet(rawScore) ? rawScore : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MatchOption
|
public class MatchOption
|
||||||
{
|
{
|
||||||
public MatchOption()
|
|
||||||
{
|
|
||||||
Prefix = "";
|
|
||||||
Suffix = "";
|
|
||||||
IgnoreCase = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// prefix of match char, use for hightlight
|
/// prefix of match char, use for hightlight
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Prefix { get; set; }
|
[Obsolete("this is never used")]
|
||||||
|
public string Prefix { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// suffix of match char, use for hightlight
|
/// suffix of match char, use for hightlight
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Suffix { get; set; }
|
[Obsolete("this is never used")]
|
||||||
|
public string Suffix { get; set; } = "";
|
||||||
|
|
||||||
public bool IgnoreCase { get; set; }
|
public bool IgnoreCase { get; set; } = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,19 +21,38 @@ namespace Wox.Infrastructure.UserSettings
|
||||||
public string ResultFontWeight { get; set; }
|
public string ResultFontWeight { get; set; }
|
||||||
public string ResultFontStretch { get; set; }
|
public string ResultFontStretch { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// when false Alphabet static service will always return empty results
|
/// when false Alphabet static service will always return empty results
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShouldUsePinyin { get; set; } = true;
|
public bool ShouldUsePinyin { get; set; } = true;
|
||||||
|
|
||||||
private string _querySearchPrecision { get; set; } = StringMatcher.SearchPrecisionScore.Regular.ToString();
|
|
||||||
public string QuerySearchPrecision
|
internal StringMatcher.SearchPrecisionScore QuerySearchPrecision { get; private set; } = StringMatcher.SearchPrecisionScore.Regular;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public string QuerySearchPrecisionString
|
||||||
{
|
{
|
||||||
get { return _querySearchPrecision; }
|
get { return QuerySearchPrecision.ToString(); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_querySearchPrecision = value;
|
try
|
||||||
StringMatcher.UserSettingSearchPrecision = value;
|
{
|
||||||
|
var precisionScore = (StringMatcher.SearchPrecisionScore)Enum
|
||||||
|
.Parse(typeof(StringMatcher.SearchPrecisionScore), value);
|
||||||
|
|
||||||
|
QuerySearchPrecision = precisionScore;
|
||||||
|
StringMatcher.Instance.UserSettingSearchPrecision = precisionScore;
|
||||||
|
}
|
||||||
|
catch (ArgumentException e)
|
||||||
|
{
|
||||||
|
Logger.Log.Exception(nameof(Settings), "Failed to load QuerySearchPrecisionString value from Settings file", e);
|
||||||
|
|
||||||
|
QuerySearchPrecision = StringMatcher.SearchPrecisionScore.Regular;
|
||||||
|
StringMatcher.Instance.UserSettingSearchPrecision = StringMatcher.SearchPrecisionScore.Regular;
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,22 +36,6 @@
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="JetBrains.Annotations, Version=10.3.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\JetBrains.Annotations.10.3.0\lib\net\JetBrains.Annotations.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\NLog.4.2.0\lib\net45\NLog.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Pinyin4Net, Version=2016.4.24.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Pinyin4DotNet.2016.4.23.4\lib\net452\Pinyin4Net.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
|
@ -71,6 +55,7 @@
|
||||||
<Compile Include="Hotkey\InterceptKeys.cs" />
|
<Compile Include="Hotkey\InterceptKeys.cs" />
|
||||||
<Compile Include="Hotkey\KeyEvent.cs" />
|
<Compile Include="Hotkey\KeyEvent.cs" />
|
||||||
<Compile Include="Image\ImageCache.cs" />
|
<Compile Include="Image\ImageCache.cs" />
|
||||||
|
<Compile Include="Image\ImageHashGenerator.cs" />
|
||||||
<Compile Include="Image\ImageLoader.cs" />
|
<Compile Include="Image\ImageLoader.cs" />
|
||||||
<Compile Include="Image\ThumbnailReader.cs" />
|
<Compile Include="Image\ThumbnailReader.cs" />
|
||||||
<Compile Include="Logger\Log.cs" />
|
<Compile Include="Logger\Log.cs" />
|
||||||
|
|
@ -101,14 +86,31 @@
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>9.0.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NLog">
|
||||||
|
<Version>4.2.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NLog.Schema" GeneratePathProperty="true">
|
||||||
|
<Version>4.2.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Pinyin4DotNet" GeneratePathProperty="true">
|
||||||
|
<Version>2016.4.23.4</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PreBuildEvent>cd $(SolutionDir)packages\Pinyin4DotNet*\pinyindb\
|
<PreBuildEvent>
|
||||||
xcopy /Y unicode_to_hanyu_pinyin.txt $(TargetDir)pinyindb\
|
xcopy /Y $(PkgPinyin4DotNet)\pinyindb\unicode_to_hanyu_pinyin.txt $(TargetDir)pinyindb\
|
||||||
cd $(SolutionDir)packages\NLog.Schema*\content\
|
xcopy /Y $(PkgNLog_Schema)\content\NLog.xsd $(TargetDir)
|
||||||
xcopy /Y NLog.xsd $(TargetDir)</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ namespace Wox.Infrastructure
|
||||||
public static readonly string DataDirectory = DetermineDataDirectory();
|
public static readonly string DataDirectory = DetermineDataDirectory();
|
||||||
public static readonly string PluginsDirectory = Path.Combine(DataDirectory, Plugins);
|
public static readonly string PluginsDirectory = Path.Combine(DataDirectory, Plugins);
|
||||||
public static readonly string PreinstalledDirectory = Path.Combine(ProgramDirectory, Plugins);
|
public static readonly string PreinstalledDirectory = Path.Combine(ProgramDirectory, Plugins);
|
||||||
public const string Repository = "https://github.com/Wox-launcher/Wox";
|
|
||||||
public const string Issue = "https://github.com/Wox-launcher/Wox/issues/new";
|
public const string Issue = "https://github.com/Wox-launcher/Wox/issues/new";
|
||||||
public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).ProductVersion;
|
public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).ProductVersion;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
|
||||||
<package id="NLog" version="4.2.0" targetFramework="net452" />
|
|
||||||
<package id="NLog.Schema" version="4.2.0" targetFramework="net452" />
|
|
||||||
<package id="Pinyin4DotNet" version="2016.4.23.4" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using PropertyChanged;
|
|
||||||
|
|
||||||
namespace Wox.Plugin
|
namespace Wox.Plugin
|
||||||
{
|
{
|
||||||
[ImplementPropertyChanged]
|
|
||||||
public class BaseModel : INotifyPropertyChanged
|
public class BaseModel : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ namespace Wox.Plugin
|
||||||
/// <param name="title">Message title</param>
|
/// <param name="title">Message title</param>
|
||||||
/// <param name="subTitle">Message subtitle</param>
|
/// <param name="subTitle">Message subtitle</param>
|
||||||
/// <param name="iconPath">Message icon path (relative path to your plugin folder)</param>
|
/// <param name="iconPath">Message icon path (relative path to your plugin folder)</param>
|
||||||
void ShowMsg(string title, string subTitle = "", string iconPath = "");
|
void ShowMsg(string title, string subTitle = "", string iconPath = "", bool useMainWindowAsOwner = true);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Open setting dialog
|
/// Open setting dialog
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PropertyChanged;
|
|
||||||
namespace Wox.Plugin
|
namespace Wox.Plugin
|
||||||
{
|
{
|
||||||
[JsonObject(MemberSerialization.OptOut)]
|
[JsonObject(MemberSerialization.OptOut)]
|
||||||
|
|
@ -46,6 +46,9 @@ namespace Wox.Plugin
|
||||||
[Obsolete("Use IcoPath")]
|
[Obsolete("Use IcoPath")]
|
||||||
public string FullIcoPath => IcoPath;
|
public string FullIcoPath => IcoPath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Init time include both plugin load time and init time
|
||||||
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public long InitTime { get; set; }
|
public long InitTime { get; set; }
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,16 @@ namespace Wox.Plugin
|
||||||
|
|
||||||
public int Score { get; set; }
|
public int Score { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of indexes for the characters to be highlighted in Title
|
||||||
|
/// </summary>
|
||||||
|
public IList<int> TitleHighlightData { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of indexes for the characters to be highlighted in SubTitle
|
||||||
|
/// </summary>
|
||||||
|
public IList<int> SubTitleHighlightData { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Only resulsts that originQuery match with curren query will be displayed in the panel
|
/// Only resulsts that originQuery match with curren query will be displayed in the panel
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -69,7 +79,9 @@ namespace Wox.Plugin
|
||||||
|
|
||||||
var equality = string.Equals(r?.Title, Title) &&
|
var equality = string.Equals(r?.Title, Title) &&
|
||||||
string.Equals(r?.SubTitle, SubTitle) &&
|
string.Equals(r?.SubTitle, SubTitle) &&
|
||||||
string.Equals(r?.IcoPath, IcoPath);
|
string.Equals(r?.IcoPath, IcoPath) &&
|
||||||
|
TitleHighlightData == r.TitleHighlightData &&
|
||||||
|
SubTitleHighlightData == r.SubTitleHighlightData;
|
||||||
|
|
||||||
return equality;
|
return equality;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
76
Wox.Plugin/SharedCommands/ShellCommand.cs
Normal file
76
Wox.Plugin/SharedCommands/ShellCommand.cs
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Wox.Plugin.SharedCommands
|
||||||
|
{
|
||||||
|
public static class ShellCommand
|
||||||
|
{
|
||||||
|
public delegate bool EnumThreadDelegate(IntPtr hwnd, IntPtr lParam);
|
||||||
|
[DllImport("user32.dll")] static extern bool EnumThreadWindows(uint threadId, EnumThreadDelegate lpfn, IntPtr lParam);
|
||||||
|
[DllImport("user32.dll")] static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int nMaxCount);
|
||||||
|
[DllImport("user32.dll")] static extern int GetWindowTextLength(IntPtr hwnd);
|
||||||
|
|
||||||
|
private static bool containsSecurityWindow;
|
||||||
|
|
||||||
|
public static Process RunAsDifferentUser(ProcessStartInfo processStartInfo)
|
||||||
|
{
|
||||||
|
processStartInfo.Verb = "RunAsUser";
|
||||||
|
var process = Process.Start(processStartInfo);
|
||||||
|
|
||||||
|
containsSecurityWindow = false;
|
||||||
|
while (!containsSecurityWindow) // wait for windows to bring up the "Windows Security" dialog
|
||||||
|
{
|
||||||
|
CheckSecurityWindow();
|
||||||
|
Thread.Sleep(25);
|
||||||
|
}
|
||||||
|
while (containsSecurityWindow) // while this process contains a "Windows Security" dialog, stay open
|
||||||
|
{
|
||||||
|
containsSecurityWindow = false;
|
||||||
|
CheckSecurityWindow();
|
||||||
|
Thread.Sleep(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CheckSecurityWindow()
|
||||||
|
{
|
||||||
|
ProcessThreadCollection ptc = Process.GetCurrentProcess().Threads;
|
||||||
|
for (int i = 0; i < ptc.Count; i++)
|
||||||
|
EnumThreadWindows((uint)ptc[i].Id, CheckSecurityThread, IntPtr.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool CheckSecurityThread(IntPtr hwnd, IntPtr lParam)
|
||||||
|
{
|
||||||
|
if (GetWindowTitle(hwnd) == "Windows Security")
|
||||||
|
containsSecurityWindow = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetWindowTitle(IntPtr hwnd)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder(GetWindowTextLength(hwnd) + 1);
|
||||||
|
GetWindowText(hwnd, sb, sb.Capacity);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProcessStartInfo SetProcessStartInfo(this string fileName, string workingDirectory = "", string arguments = "", string verb = "")
|
||||||
|
{
|
||||||
|
var info = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = fileName,
|
||||||
|
WorkingDirectory = workingDirectory,
|
||||||
|
Arguments = arguments,
|
||||||
|
Verb = verb
|
||||||
|
};
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -36,20 +36,8 @@
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="JetBrains.Annotations, Version=10.3.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\JetBrains.Annotations.10.3.0\lib\net\JetBrains.Annotations.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="PropertyChanged, Version=1.51.0.0, Culture=neutral, PublicKeyToken=ee3ee20bcf148ddd, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\PropertyChanged.Fody.1.51.0\lib\dotnet\PropertyChanged.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Xaml" />
|
<Reference Include="System.Xaml" />
|
||||||
|
|
@ -78,23 +66,39 @@
|
||||||
<Compile Include="Result.cs" />
|
<Compile Include="Result.cs" />
|
||||||
<Compile Include="ActionContext.cs" />
|
<Compile Include="ActionContext.cs" />
|
||||||
<Compile Include="SharedCommands\SearchWeb.cs" />
|
<Compile Include="SharedCommands\SearchWeb.cs" />
|
||||||
|
<Compile Include="SharedCommands\ShellCommand.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="README.md" />
|
<None Include="README.md" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="FodyWeavers.xml" />
|
<Content Include="FodyWeavers.xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Fody">
|
||||||
|
<Version>1.29.2</Version>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Mono.Cecil">
|
||||||
|
<Version>0.9.6.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>9.0.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="PropertyChanged.Fody">
|
||||||
|
<Version>1.51.0</Version>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="..\packages\Fody.1.29.2\build\dotnet\Fody.targets" Condition="Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" />
|
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Error Condition="!Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.29.2\build\dotnet\Fody.targets'))" />
|
|
||||||
</Target>
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="Fody" version="1.29.2" targetFramework="net452" developmentDependency="true" />
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
|
||||||
<package id="PropertyChanged.Fody" version="1.51.0" targetFramework="net452" developmentDependency="true" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -11,17 +11,25 @@ namespace Wox.Test
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class FuzzyMatcherTest
|
public class FuzzyMatcherTest
|
||||||
{
|
{
|
||||||
public List<string> GetSearchStrings()
|
private const string Chrome = "Chrome";
|
||||||
|
private const string CandyCrushSagaFromKing = "Candy Crush Saga from King";
|
||||||
|
private const string HelpCureHopeRaiseOnMindEntityChrome = "Help cure hope raise on mind entity Chrome";
|
||||||
|
private const string UninstallOrChangeProgramsOnYourComputer = "Uninstall or change programs on your computer";
|
||||||
|
private const string LastIsChrome = "Last is chrome";
|
||||||
|
private const string OneOneOneOne = "1111";
|
||||||
|
private const string MicrosoftSqlServerManagementStudio = "Microsoft SQL Server Management Studio";
|
||||||
|
|
||||||
|
public List<string> GetSearchStrings()
|
||||||
=> new List<string>
|
=> new List<string>
|
||||||
{
|
{
|
||||||
"Chrome",
|
Chrome,
|
||||||
"Choose which programs you want Windows to use for activities like web browsing, editing photos, sending e-mail, and playing music.",
|
"Choose which programs you want Windows to use for activities like web browsing, editing photos, sending e-mail, and playing music.",
|
||||||
"Help cure hope raise on mind entity Chrome ",
|
HelpCureHopeRaiseOnMindEntityChrome,
|
||||||
"Candy Crush Saga from King",
|
CandyCrushSagaFromKing,
|
||||||
"Uninstall or change programs on your computer",
|
UninstallOrChangeProgramsOnYourComputer,
|
||||||
"Add, change, and manage fonts on your computer",
|
"Add, change, and manage fonts on your computer",
|
||||||
"Last is chrome",
|
LastIsChrome,
|
||||||
"1111"
|
OneOneOneOne
|
||||||
};
|
};
|
||||||
|
|
||||||
public List<int> GetPrecisionScores()
|
public List<int> GetPrecisionScores()
|
||||||
|
|
@ -48,14 +56,14 @@ namespace Wox.Test
|
||||||
"aac"
|
"aac"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var results = new List<Result>();
|
var results = new List<Result>();
|
||||||
|
var matcher = new StringMatcher();
|
||||||
foreach (var str in sources)
|
foreach (var str in sources)
|
||||||
{
|
{
|
||||||
results.Add(new Result
|
results.Add(new Result
|
||||||
{
|
{
|
||||||
Title = str,
|
Title = str,
|
||||||
Score = StringMatcher.FuzzySearch("inst", str).Score
|
Score = matcher.FuzzyMatch("inst", str).RawScore
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,30 +79,30 @@ namespace Wox.Test
|
||||||
public void WhenGivenNotAllCharactersFoundInSearchStringThenShouldReturnZeroScore(string searchString)
|
public void WhenGivenNotAllCharactersFoundInSearchStringThenShouldReturnZeroScore(string searchString)
|
||||||
{
|
{
|
||||||
var compareString = "Can have rum only in my glass";
|
var compareString = "Can have rum only in my glass";
|
||||||
|
var matcher = new StringMatcher();
|
||||||
var scoreResult = StringMatcher.FuzzySearch(searchString, compareString).Score;
|
var scoreResult = matcher.FuzzyMatch(searchString, compareString).RawScore;
|
||||||
|
|
||||||
Assert.True(scoreResult == 0);
|
Assert.True(scoreResult == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("chr")]
|
[TestCase("chr")]
|
||||||
[TestCase("chrom")]
|
[TestCase("chrom")]
|
||||||
[TestCase("chrome")]
|
[TestCase("chrome")]
|
||||||
[TestCase("cand")]
|
[TestCase("cand")]
|
||||||
[TestCase("cpywa")]
|
[TestCase("cpywa")]
|
||||||
[TestCase("ccs")]
|
[TestCase("ccs")]
|
||||||
public void WhenGivenStringsAndAppliedPrecisionFilteringThenShouldReturnGreaterThanPrecisionScoreResults(string searchTerm)
|
public void WhenGivenStringsAndAppliedPrecisionFilteringThenShouldReturnGreaterThanPrecisionScoreResults(string searchTerm)
|
||||||
{
|
{
|
||||||
var results = new List<Result>();
|
var results = new List<Result>();
|
||||||
|
var matcher = new StringMatcher();
|
||||||
foreach (var str in GetSearchStrings())
|
foreach (var str in GetSearchStrings())
|
||||||
{
|
{
|
||||||
results.Add(new Result
|
results.Add(new Result
|
||||||
{
|
{
|
||||||
Title = str,
|
Title = str,
|
||||||
Score = StringMatcher.FuzzySearch(searchTerm, str).Score
|
Score = matcher.FuzzyMatch(searchTerm, str).Score
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var precisionScore in GetPrecisionScores())
|
foreach (var precisionScore in GetPrecisionScores())
|
||||||
{
|
{
|
||||||
|
|
@ -114,76 +122,104 @@ namespace Wox.Test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("chrome")]
|
[TestCase(Chrome, Chrome, 137)]
|
||||||
public void WhenGivenStringsForCalScoreMethodThenShouldReturnCurrentScoring(string searchTerm)
|
[TestCase(Chrome, LastIsChrome, 83)]
|
||||||
|
[TestCase(Chrome, HelpCureHopeRaiseOnMindEntityChrome, 21)]
|
||||||
|
[TestCase(Chrome, UninstallOrChangeProgramsOnYourComputer, 15)]
|
||||||
|
[TestCase(Chrome, CandyCrushSagaFromKing, 0)]
|
||||||
|
[TestCase("sql", MicrosoftSqlServerManagementStudio, 56)]
|
||||||
|
[TestCase("sql manag", MicrosoftSqlServerManagementStudio, 79)]//double spacing intended
|
||||||
|
public void WhenGivenQueryStringThenShouldReturnCurrentScoring(string queryString, string compareString, int expectedScore)
|
||||||
{
|
{
|
||||||
var searchStrings = new List<string>
|
// When, Given
|
||||||
{
|
var matcher = new StringMatcher();
|
||||||
"Chrome",//SCORE: 107
|
var rawScore = matcher.FuzzyMatch(queryString, compareString).RawScore;
|
||||||
"Last is chrome",//SCORE: 53
|
|
||||||
"Help cure hope raise on mind entity Chrome",//SCORE: 21
|
|
||||||
"Uninstall or change programs on your computer", //SCORE: 15
|
|
||||||
"Candy Crush Saga from King"//SCORE: 0
|
|
||||||
}
|
|
||||||
.OrderByDescending(x => x)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var results = new List<Result>();
|
// Should
|
||||||
|
Assert.AreEqual(expectedScore, rawScore, $"Expected score for compare string '{compareString}': {expectedScore}, Actual: {rawScore}");
|
||||||
foreach (var str in searchStrings)
|
|
||||||
{
|
|
||||||
results.Add(new Result
|
|
||||||
{
|
|
||||||
Title = str,
|
|
||||||
Score = StringMatcher.FuzzySearch(searchTerm, str).Score
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var orderedResults = results.OrderByDescending(x => x.Title).ToList();
|
|
||||||
|
|
||||||
Debug.WriteLine("");
|
|
||||||
Debug.WriteLine("###############################################");
|
|
||||||
Debug.WriteLine("SEARCHTERM: " + searchTerm);
|
|
||||||
foreach (var item in orderedResults)
|
|
||||||
{
|
|
||||||
Debug.WriteLine("SCORE: " + item.Score.ToString() + ", FoundString: " + item.Title);
|
|
||||||
}
|
|
||||||
Debug.WriteLine("###############################################");
|
|
||||||
Debug.WriteLine("");
|
|
||||||
|
|
||||||
Assert.IsTrue(orderedResults[0].Score == 15 && orderedResults[0].Title == searchStrings[0]);
|
|
||||||
Assert.IsTrue(orderedResults[1].Score == 53 && orderedResults[1].Title == searchStrings[1]);
|
|
||||||
Assert.IsTrue(orderedResults[2].Score == 21 && orderedResults[2].Title == searchStrings[2]);
|
|
||||||
Assert.IsTrue(orderedResults[3].Score == 107 && orderedResults[3].Title == searchStrings[3]);
|
|
||||||
Assert.IsTrue(orderedResults[4].Score == 0 && orderedResults[4].Title == searchStrings[4]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("goo", "Google Chrome", (int)StringMatcher.SearchPrecisionScore.Regular, true)]
|
[TestCase("goo", "Google Chrome", StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
[TestCase("chr", "Google Chrome", (int)StringMatcher.SearchPrecisionScore.Low, true)]
|
[TestCase("chr", "Google Chrome", StringMatcher.SearchPrecisionScore.Low, true)]
|
||||||
[TestCase("chr", "Chrome", (int)StringMatcher.SearchPrecisionScore.Regular, true)]
|
[TestCase("chr", "Chrome", StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
[TestCase("chr", "Help cure hope raise on mind entity Chrome", (int)StringMatcher.SearchPrecisionScore.Regular, false)]
|
[TestCase("chr", "Help cure hope raise on mind entity Chrome", StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
[TestCase("chr", "Help cure hope raise on mind entity Chrome", (int)StringMatcher.SearchPrecisionScore.Low, true)]
|
[TestCase("chr", "Help cure hope raise on mind entity Chrome", StringMatcher.SearchPrecisionScore.Low, true)]
|
||||||
[TestCase("chr", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.Regular, false)]
|
[TestCase("chr", "Candy Crush Saga from King", StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
[TestCase("chr", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.None, true)]
|
[TestCase("chr", "Candy Crush Saga from King", StringMatcher.SearchPrecisionScore.None, true)]
|
||||||
[TestCase("ccs", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.Low, true)]
|
[TestCase("ccs", "Candy Crush Saga from King", StringMatcher.SearchPrecisionScore.Low, true)]
|
||||||
[TestCase("cand", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.Regular, true)]
|
[TestCase("cand", "Candy Crush Saga from King",StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
[TestCase("cand", "Help cure hope raise on mind entity Chrome", (int)StringMatcher.SearchPrecisionScore.Regular, false)]
|
[TestCase("cand", "Help cure hope raise on mind entity Chrome", StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
public void WhenGivenDesiredPrecisionThenShouldReturnAllResultsGreaterOrEqual(string queryString, string compareString,
|
public void WhenGivenDesiredPrecisionThenShouldReturnAllResultsGreaterOrEqual(
|
||||||
int expectedPrecisionScore, bool expectedPrecisionResult)
|
string queryString,
|
||||||
|
string compareString,
|
||||||
|
StringMatcher.SearchPrecisionScore expectedPrecisionScore,
|
||||||
|
bool expectedPrecisionResult)
|
||||||
{
|
{
|
||||||
var expectedPrecisionString = (StringMatcher.SearchPrecisionScore)expectedPrecisionScore;
|
// When
|
||||||
StringMatcher.UserSettingSearchPrecision = expectedPrecisionString.ToString();
|
var matcher = new StringMatcher {UserSettingSearchPrecision = expectedPrecisionScore};
|
||||||
var matchResult = StringMatcher.FuzzySearch(queryString, compareString);
|
|
||||||
|
// Given
|
||||||
|
var matchResult = matcher.FuzzyMatch(queryString, compareString);
|
||||||
|
|
||||||
Debug.WriteLine("");
|
Debug.WriteLine("");
|
||||||
Debug.WriteLine("###############################################");
|
Debug.WriteLine("###############################################");
|
||||||
Debug.WriteLine($"SearchTerm: {queryString} PrecisionLevelSetAt: {expectedPrecisionString} ({expectedPrecisionScore})");
|
Debug.WriteLine($"QueryString: {queryString} CompareString: {compareString}");
|
||||||
Debug.WriteLine($"SCORE: {matchResult.Score.ToString()}, ComparedString: {compareString}");
|
Debug.WriteLine($"RAW SCORE: {matchResult.RawScore.ToString()}, PrecisionLevelSetAt: {expectedPrecisionScore} ({(int)expectedPrecisionScore})");
|
||||||
Debug.WriteLine("###############################################");
|
Debug.WriteLine("###############################################");
|
||||||
Debug.WriteLine("");
|
Debug.WriteLine("");
|
||||||
|
|
||||||
var matchPrecisionResult = matchResult.IsSearchPrecisionScoreMet();
|
// Should
|
||||||
Assert.IsTrue(matchPrecisionResult == expectedPrecisionResult);
|
Assert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(),
|
||||||
|
$"Query:{queryString}{Environment.NewLine} " +
|
||||||
|
$"Compare:{compareString}{Environment.NewLine}" +
|
||||||
|
$"Raw Score: {matchResult.RawScore}{Environment.NewLine}" +
|
||||||
|
$"Precision Score: {(int)expectedPrecisionScore}");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("exce", "OverLeaf-Latex: An online LaTeX editor", StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
|
[TestCase("term", "Windows Terminal (Preview)", StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
[TestCase("sql s managa", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
|
[TestCase("sql' s manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
|
[TestCase("sql s manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
[TestCase("sql manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
[TestCase("sql", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
[TestCase("sql serv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
[TestCase("sqlserv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
|
[TestCase("sql servman", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
|
[TestCase("sql serv man", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
[TestCase("sql studio", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
[TestCase("mic", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
[TestCase("chr", "Shutdown", StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
|
[TestCase("mssms", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
|
[TestCase("chr", "Change settings for text-to-speech and for speech recognition (if installed).", StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
|
[TestCase("ch r", "Change settings for text-to-speech and for speech recognition (if installed).", StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
[TestCase("a test", "This is a test", StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
[TestCase("test", "This is a test", StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||||
|
public void WhenGivenQueryShouldReturnResultsContainingAllQuerySubstrings(
|
||||||
|
string queryString,
|
||||||
|
string compareString,
|
||||||
|
StringMatcher.SearchPrecisionScore expectedPrecisionScore,
|
||||||
|
bool expectedPrecisionResult)
|
||||||
|
{
|
||||||
|
// When
|
||||||
|
var matcher = new StringMatcher { UserSettingSearchPrecision = expectedPrecisionScore };
|
||||||
|
|
||||||
|
// Given
|
||||||
|
var matchResult = matcher.FuzzyMatch(queryString, compareString);
|
||||||
|
|
||||||
|
Debug.WriteLine("");
|
||||||
|
Debug.WriteLine("###############################################");
|
||||||
|
Debug.WriteLine($"QueryString: {queryString} CompareString: {compareString}");
|
||||||
|
Debug.WriteLine($"RAW SCORE: {matchResult.RawScore.ToString()}, PrecisionLevelSetAt: {expectedPrecisionScore} ({(int)expectedPrecisionScore})");
|
||||||
|
Debug.WriteLine("###############################################");
|
||||||
|
Debug.WriteLine("");
|
||||||
|
|
||||||
|
// Should
|
||||||
|
Assert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(),
|
||||||
|
$"Query:{queryString}{Environment.NewLine} " +
|
||||||
|
$"Compare:{compareString}{Environment.NewLine}" +
|
||||||
|
$"Raw Score: {matchResult.RawScore}{Environment.NewLine}" +
|
||||||
|
$"Precision Score: {(int)expectedPrecisionScore}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<Import Project="..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
|
|
||||||
<Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
|
@ -38,13 +36,6 @@
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Moq, Version=4.2.1409.1722, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
@ -77,16 +68,17 @@
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<PackageReference Include="Moq">
|
||||||
|
<Version>4.2.1409.1722</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NUnit">
|
||||||
|
<Version>3.12.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NUnit3TestAdapter">
|
||||||
|
<Version>3.15.1</Version>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" />
|
|
||||||
<Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
|
|
||||||
</Target>
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="Moq" version="4.2.1409.1722" targetFramework="net452" />
|
|
||||||
<package id="NUnit" version="3.12.0" targetFramework="net452" />
|
|
||||||
<package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -1,7 +1,19 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!--https://msdn.microsoft.com/en-us/library/dd409252(v=vs.110).aspx-->
|
<!--https://msdn.microsoft.com/en-us/library/dd409252(v=vs.110).aspx-->
|
||||||
|
<configSections>
|
||||||
|
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||||
|
<section name="Wox.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||||
|
</sectionGroup>
|
||||||
|
</configSections>
|
||||||
<runtime>
|
<runtime>
|
||||||
<loadFromRemoteSources enabled="true"/>
|
<loadFromRemoteSources enabled="true"/>
|
||||||
</runtime>
|
</runtime>
|
||||||
|
<applicationSettings>
|
||||||
|
<Wox.Properties.Settings>
|
||||||
|
<setting name="GithubRepo" serializeAs="String">
|
||||||
|
<value>https://github.com/Wox-launcher/Wox</value>
|
||||||
|
</setting>
|
||||||
|
</Wox.Properties.Settings>
|
||||||
|
</applicationSettings>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
|
|
@ -25,6 +25,9 @@ namespace Wox
|
||||||
private Settings _settings;
|
private Settings _settings;
|
||||||
private MainViewModel _mainVM;
|
private MainViewModel _mainVM;
|
||||||
private SettingWindowViewModel _settingsVM;
|
private SettingWindowViewModel _settingsVM;
|
||||||
|
private readonly Updater _updater = new Updater(Wox.Properties.Settings.Default.GithubRepo);
|
||||||
|
private readonly Alphabet _alphabet = new Alphabet();
|
||||||
|
private StringMatcher _stringMatcher;
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
public static void Main()
|
public static void Main()
|
||||||
|
|
@ -50,17 +53,18 @@ namespace Wox
|
||||||
|
|
||||||
ImageLoader.Initialize();
|
ImageLoader.Initialize();
|
||||||
|
|
||||||
_settingsVM = new SettingWindowViewModel();
|
_settingsVM = new SettingWindowViewModel(_updater);
|
||||||
_settings = _settingsVM.Settings;
|
_settings = _settingsVM.Settings;
|
||||||
|
|
||||||
Alphabet.Initialize(_settings);
|
_alphabet.Initialize(_settings);
|
||||||
|
_stringMatcher = new StringMatcher(_alphabet);
|
||||||
StringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
|
StringMatcher.Instance = _stringMatcher;
|
||||||
|
_stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
|
||||||
|
|
||||||
PluginManager.LoadPlugins(_settings.PluginSettings);
|
PluginManager.LoadPlugins(_settings.PluginSettings);
|
||||||
_mainVM = new MainViewModel(_settings);
|
_mainVM = new MainViewModel(_settings);
|
||||||
var window = new MainWindow(_settings, _mainVM);
|
var window = new MainWindow(_settings, _mainVM);
|
||||||
API = new PublicAPIInstance(_settingsVM, _mainVM);
|
API = new PublicAPIInstance(_settingsVM, _mainVM, _alphabet);
|
||||||
PluginManager.InitializePlugins(API);
|
PluginManager.InitializePlugins(API);
|
||||||
Log.Info($"|App.OnStartup|Dependencies Info:{ErrorReporting.DependenciesInfo()}");
|
Log.Info($"|App.OnStartup|Dependencies Info:{ErrorReporting.DependenciesInfo()}");
|
||||||
|
|
||||||
|
|
@ -110,12 +114,12 @@ namespace Wox
|
||||||
var timer = new Timer(1000 * 60 * 60 * 5);
|
var timer = new Timer(1000 * 60 * 60 * 5);
|
||||||
timer.Elapsed += async (s, e) =>
|
timer.Elapsed += async (s, e) =>
|
||||||
{
|
{
|
||||||
await Updater.UpdateApp();
|
await _updater.UpdateApp();
|
||||||
};
|
};
|
||||||
timer.Start();
|
timer.Start();
|
||||||
|
|
||||||
// check updates on startup
|
// check updates on startup
|
||||||
await Updater.UpdateApp();
|
await _updater.UpdateApp();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -144,10 +148,6 @@ namespace Wox
|
||||||
private static void RegisterAppDomainExceptions()
|
private static void RegisterAppDomainExceptions()
|
||||||
{
|
{
|
||||||
AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledExceptionHandle;
|
AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledExceptionHandle;
|
||||||
AppDomain.CurrentDomain.FirstChanceException += (_, e) =>
|
|
||||||
{
|
|
||||||
Log.Exception("|App.RegisterAppDomainExceptions|First Chance Exception:", e.Exception);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
@ -156,13 +156,7 @@ namespace Wox
|
||||||
// but if sessionending is not called, exit won't be called when log off / shutdown
|
// but if sessionending is not called, exit won't be called when log off / shutdown
|
||||||
if (!_disposed)
|
if (!_disposed)
|
||||||
{
|
{
|
||||||
_mainVM.Save();
|
API.SaveAppAllSettings();
|
||||||
_settingsVM.Save();
|
|
||||||
|
|
||||||
PluginManager.Save();
|
|
||||||
ImageLoader.Save();
|
|
||||||
Alphabet.Save();
|
|
||||||
|
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
53
Wox/Converters/HighlightTextConverter.cs
Normal file
53
Wox/Converters/HighlightTextConverter.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
|
||||||
|
namespace Wox.Converters
|
||||||
|
{
|
||||||
|
public class HighlightTextConverter : IMultiValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object[] value, Type targetType, object parameter, CultureInfo cultureInfo)
|
||||||
|
{
|
||||||
|
var text = value[0] as string;
|
||||||
|
var highlightData = value[1] as List<int>;
|
||||||
|
|
||||||
|
var textBlock = new Span();
|
||||||
|
|
||||||
|
if (highlightData == null || !highlightData.Any())
|
||||||
|
{
|
||||||
|
// No highlight data, just return the text
|
||||||
|
return new Run(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < text.Length; i++)
|
||||||
|
{
|
||||||
|
var currentCharacter = text.Substring(i, 1);
|
||||||
|
if (this.ShouldHighlight(highlightData, i))
|
||||||
|
{
|
||||||
|
textBlock.Inlines.Add(new Bold(new Run(currentCharacter)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textBlock.Inlines.Add(new Run(currentCharacter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return textBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return new[] { DependencyProperty.UnsetValue, DependencyProperty.UnsetValue };
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldHighlight(List<int> highlightData, int index)
|
||||||
|
{
|
||||||
|
return highlightData.Contains(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -87,4 +87,4 @@
|
||||||
</ContentControl>
|
</ContentControl>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</Window>
|
</Window>
|
||||||
|
|
|
||||||
11
Wox/Properties/Settings.Designer.cs
generated
11
Wox/Properties/Settings.Designer.cs
generated
|
|
@ -12,7 +12,7 @@ namespace Wox.Properties {
|
||||||
|
|
||||||
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.3.0.0")]
|
||||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
@ -22,5 +22,14 @@ namespace Wox.Properties {
|
||||||
return defaultInstance;
|
return defaultInstance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("https://github.com/Wox-launcher/Wox")]
|
||||||
|
public string GithubRepo {
|
||||||
|
get {
|
||||||
|
return ((string)(this["GithubRepo"]));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<SettingsFile xmlns="uri:_settings" CurrentProfile="(Default)">
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Wox.Properties" GeneratedClassName="Settings">
|
||||||
<Profiles>
|
<Profiles />
|
||||||
<Profile Name="(Default)" />
|
<Settings>
|
||||||
</Profiles>
|
<Setting Name="GithubRepo" Type="System.String" Scope="Application">
|
||||||
<Settings />
|
<Value Profile="(Default)">https://github.com/Wox-launcher/Wox</Value>
|
||||||
|
</Setting>
|
||||||
|
</Settings>
|
||||||
</SettingsFile>
|
</SettingsFile>
|
||||||
|
|
@ -20,16 +20,17 @@ namespace Wox
|
||||||
{
|
{
|
||||||
private readonly SettingWindowViewModel _settingsVM;
|
private readonly SettingWindowViewModel _settingsVM;
|
||||||
private readonly MainViewModel _mainVM;
|
private readonly MainViewModel _mainVM;
|
||||||
|
private readonly Alphabet _alphabet;
|
||||||
|
|
||||||
#region Constructor
|
#region Constructor
|
||||||
|
|
||||||
public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM)
|
public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, Alphabet alphabet)
|
||||||
{
|
{
|
||||||
_settingsVM = settingsVM;
|
_settingsVM = settingsVM;
|
||||||
_mainVM = mainVM;
|
_mainVM = mainVM;
|
||||||
|
_alphabet = alphabet;
|
||||||
GlobalHotkey.Instance.hookedKeyboardCallback += KListener_hookedKeyboardCallback;
|
GlobalHotkey.Instance.hookedKeyboardCallback += KListener_hookedKeyboardCallback;
|
||||||
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
|
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
@ -70,7 +71,7 @@ namespace Wox
|
||||||
_settingsVM.Save();
|
_settingsVM.Save();
|
||||||
PluginManager.Save();
|
PluginManager.Save();
|
||||||
ImageLoader.Save();
|
ImageLoader.Save();
|
||||||
Alphabet.Save();
|
_alphabet.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReloadAllPluginData()
|
public void ReloadAllPluginData()
|
||||||
|
|
@ -90,12 +91,12 @@ namespace Wox
|
||||||
_mainVM.MainWindowVisibility = Visibility.Visible;
|
_mainVM.MainWindowVisibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowMsg(string title, string subTitle = "", string iconPath = "")
|
public void ShowMsg(string title, string subTitle = "", string iconPath = "", bool useMainWindowAsOwner = true)
|
||||||
{
|
{
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
var m = new Msg { Owner = Application.Current.MainWindow };
|
var msg = useMainWindowAsOwner ? new Msg {Owner = Application.Current.MainWindow} : new Msg();
|
||||||
m.Show(title, subTitle, iconPath);
|
msg.Show(title, subTitle, iconPath);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Wox
|
||||||
|
|
||||||
private void SetException(Exception exception)
|
private void SetException(Exception exception)
|
||||||
{
|
{
|
||||||
string path = Path.Combine(Constant.DataDirectory, Log.DirectoryName, Constant.Version);
|
string path = Log.CurrentLogDirectory;
|
||||||
var directory = new DirectoryInfo(path);
|
var directory = new DirectoryInfo(path);
|
||||||
var log = directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
|
var log = directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:vm="clr-namespace:Wox.ViewModel"
|
xmlns:vm="clr-namespace:Wox.ViewModel"
|
||||||
|
xmlns:converter="clr-namespace:Wox.Converters"
|
||||||
mc:Ignorable="d" d:DesignWidth="100" d:DesignHeight="100"
|
mc:Ignorable="d" d:DesignWidth="100" d:DesignHeight="100"
|
||||||
d:DataContext="{d:DesignInstance vm:ResultsViewModel}"
|
d:DataContext="{d:DesignInstance vm:ResultsViewModel}"
|
||||||
MaxHeight="{Binding MaxHeight}"
|
MaxHeight="{Binding MaxHeight}"
|
||||||
|
|
@ -30,6 +31,9 @@
|
||||||
<Button.Content>
|
<Button.Content>
|
||||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5"
|
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5"
|
||||||
Cursor="Hand" UseLayoutRounding="False">
|
Cursor="Hand" UseLayoutRounding="False">
|
||||||
|
<Grid.Resources>
|
||||||
|
<converter:HighlightTextConverter x:Key="HighlightTextConverter"/>
|
||||||
|
</Grid.Resources>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="32" />
|
<ColumnDefinition Width="32" />
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
|
|
@ -44,9 +48,23 @@
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBlock Style="{DynamicResource ItemTitleStyle}" DockPanel.Dock="Left"
|
<TextBlock Style="{DynamicResource ItemTitleStyle}" DockPanel.Dock="Left"
|
||||||
VerticalAlignment="Center" ToolTip="{Binding Result.Title}" x:Name="Title"
|
VerticalAlignment="Center" ToolTip="{Binding Result.Title}" x:Name="Title"
|
||||||
Text="{Binding Result.Title}" />
|
Text="{Binding Result.Title}">
|
||||||
|
<vm:ResultsViewModel.FormattedText>
|
||||||
|
<MultiBinding Converter="{StaticResource HighlightTextConverter}">
|
||||||
|
<Binding Path="Result.Title" />
|
||||||
|
<Binding Path="Result.TitleHighlightData" />
|
||||||
|
</MultiBinding>
|
||||||
|
</vm:ResultsViewModel.FormattedText>
|
||||||
|
</TextBlock>
|
||||||
<TextBlock Style="{DynamicResource ItemSubTitleStyle}" ToolTip="{Binding Result.SubTitle}"
|
<TextBlock Style="{DynamicResource ItemSubTitleStyle}" ToolTip="{Binding Result.SubTitle}"
|
||||||
Grid.Row="1" x:Name="SubTitle" Text="{Binding Result.SubTitle}" />
|
Grid.Row="1" x:Name="SubTitle" Text="{Binding Result.SubTitle}">
|
||||||
|
<vm:ResultsViewModel.FormattedText>
|
||||||
|
<MultiBinding Converter="{StaticResource HighlightTextConverter}">
|
||||||
|
<Binding Path="Result.SubTitle" />
|
||||||
|
<Binding Path="Result.SubTitleHighlightData" />
|
||||||
|
</MultiBinding>
|
||||||
|
</vm:ResultsViewModel.FormattedText>
|
||||||
|
</TextBlock>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Button.Content>
|
</Button.Content>
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
<TextBlock Text="{DynamicResource querySearchPrecision}" />
|
<TextBlock Text="{DynamicResource querySearchPrecision}" />
|
||||||
<ComboBox Margin="10 0 0 0" Width="120"
|
<ComboBox Margin="10 0 0 0" Width="120"
|
||||||
ItemsSource="{Binding QuerySearchPrecisionStrings}"
|
ItemsSource="{Binding QuerySearchPrecisionStrings}"
|
||||||
SelectedItem="{Binding Settings.QuerySearchPrecision}" />
|
SelectedItem="{Binding Settings.QuerySearchPrecisionString}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="10" Orientation="Horizontal">
|
<StackPanel Margin="10" Orientation="Horizontal">
|
||||||
<TextBlock Text="{DynamicResource lastQueryMode}" />
|
<TextBlock Text="{DynamicResource lastQueryMode}" />
|
||||||
|
|
|
||||||
|
|
@ -260,53 +260,16 @@ namespace Wox
|
||||||
#region Proxy
|
#region Proxy
|
||||||
|
|
||||||
private void OnTestProxyClick(object sender, RoutedEventArgs e)
|
private void OnTestProxyClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{ // TODO: change to command
|
||||||
if (string.IsNullOrEmpty(_settings.Proxy.Server))
|
var msg = _viewModel.TestProxy();
|
||||||
{
|
MessageBox.Show(msg); // TODO: add message box service
|
||||||
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("serverCantBeEmpty"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_settings.Proxy.Port <= 0)
|
|
||||||
{
|
|
||||||
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("portCantBeEmpty"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Infrastructure.Constant.Repository);
|
|
||||||
if (string.IsNullOrEmpty(_settings.Proxy.UserName) || string.IsNullOrEmpty(_settings.Proxy.Password))
|
|
||||||
{
|
|
||||||
request.Proxy = new WebProxy(_settings.Proxy.Server, _settings.Proxy.Port);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
request.Proxy = new WebProxy(_settings.Proxy.Server, _settings.Proxy.Port)
|
|
||||||
{
|
|
||||||
Credentials = new NetworkCredential(_settings.Proxy.UserName, _settings.Proxy.Password)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = (HttpWebResponse)request.GetResponse();
|
|
||||||
if (response.StatusCode == HttpStatusCode.OK)
|
|
||||||
{
|
|
||||||
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("proxyIsCorrect"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("proxyConnectFailed"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("proxyConnectFailed"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private async void OnCheckUpdates(object sender, RoutedEventArgs e)
|
private async void OnCheckUpdates(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await Updater.UpdateApp();
|
_viewModel.UpdateApp(); // TODO: change to command
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRequestNavigate(object sender, RequestNavigateEventArgs e)
|
private void OnRequestNavigate(object sender, RequestNavigateEventArgs e)
|
||||||
|
|
|
||||||
28
Wox/Settings.cs
Normal file
28
Wox/Settings.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
namespace Wox.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
// This class allows you to handle specific events on the settings class:
|
||||||
|
// The SettingChanging event is raised before a setting's value is changed.
|
||||||
|
// The PropertyChanged event is raised after a setting's value is changed.
|
||||||
|
// The SettingsLoaded event is raised after the setting values are loaded.
|
||||||
|
// The SettingsSaving event is raised before the setting values are saved.
|
||||||
|
internal sealed partial class Settings {
|
||||||
|
|
||||||
|
public Settings() {
|
||||||
|
// // To add event handlers for saving and changing settings, uncomment the lines below:
|
||||||
|
//
|
||||||
|
// this.SettingChanging += this.SettingChangingEventHandler;
|
||||||
|
//
|
||||||
|
// this.SettingsSaving += this.SettingsSavingEventHandler;
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
|
||||||
|
// Add code to handle the SettingChangingEvent event here.
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||||
|
// Add code to handle the SettingsSaving event here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,6 @@ using Wox.Core.Resource;
|
||||||
using Wox.Helper;
|
using Wox.Helper;
|
||||||
using Wox.Infrastructure;
|
using Wox.Infrastructure;
|
||||||
using Wox.Infrastructure.Hotkey;
|
using Wox.Infrastructure.Hotkey;
|
||||||
using Wox.Infrastructure.Image;
|
|
||||||
using Wox.Infrastructure.Storage;
|
using Wox.Infrastructure.Storage;
|
||||||
using Wox.Infrastructure.UserSettings;
|
using Wox.Infrastructure.UserSettings;
|
||||||
using Wox.Plugin;
|
using Wox.Plugin;
|
||||||
|
|
@ -25,7 +24,7 @@ namespace Wox.ViewModel
|
||||||
{
|
{
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
private bool _queryHasReturn;
|
private bool _isQueryRunning;
|
||||||
private Query _lastQuery;
|
private Query _lastQuery;
|
||||||
private string _queryTextBeforeLeaveResults;
|
private string _queryTextBeforeLeaveResults;
|
||||||
|
|
||||||
|
|
@ -41,7 +40,7 @@ namespace Wox.ViewModel
|
||||||
private CancellationToken _updateToken;
|
private CancellationToken _updateToken;
|
||||||
private bool _saved;
|
private bool _saved;
|
||||||
|
|
||||||
private Internationalization _translator = InternationalizationManager.Instance;
|
private readonly Internationalization _translator = InternationalizationManager.Instance;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
@ -312,7 +311,7 @@ namespace Wox.ViewModel
|
||||||
{
|
{
|
||||||
var filtered = results.Where
|
var filtered = results.Where
|
||||||
(
|
(
|
||||||
r => StringMatcher.FuzzySearch(query, r.Title).IsSearchPrecisionScoreMet()
|
r => StringMatcher.FuzzySearch(query, r.Title).IsSearchPrecisionScoreMet()
|
||||||
|| StringMatcher.FuzzySearch(query, r.SubTitle).IsSearchPrecisionScoreMet()
|
|| StringMatcher.FuzzySearch(query, r.SubTitle).IsSearchPrecisionScoreMet()
|
||||||
).ToList();
|
).ToList();
|
||||||
ContextMenu.AddResults(filtered, id);
|
ContextMenu.AddResults(filtered, id);
|
||||||
|
|
@ -371,63 +370,59 @@ namespace Wox.ViewModel
|
||||||
if (!string.IsNullOrEmpty(QueryText))
|
if (!string.IsNullOrEmpty(QueryText))
|
||||||
{
|
{
|
||||||
_updateSource?.Cancel();
|
_updateSource?.Cancel();
|
||||||
_updateSource = new CancellationTokenSource();
|
var currentUpdateSource = new CancellationTokenSource();
|
||||||
_updateToken = _updateSource.Token;
|
_updateSource = currentUpdateSource;
|
||||||
|
var currentCancellationToken = _updateSource.Token;
|
||||||
|
_updateToken = currentCancellationToken;
|
||||||
|
|
||||||
ProgressBarVisibility = Visibility.Hidden;
|
ProgressBarVisibility = Visibility.Hidden;
|
||||||
_queryHasReturn = false;
|
_isQueryRunning = true;
|
||||||
var query = PluginManager.QueryInit(QueryText.Trim());
|
var query = PluginManager.QueryInit(QueryText.Trim());
|
||||||
if (query != null)
|
if (query != null)
|
||||||
{
|
{
|
||||||
// handle the exclusiveness of plugin using action keyword
|
// handle the exclusiveness of plugin using action keyword
|
||||||
string lastKeyword = _lastQuery.ActionKeyword;
|
RemoveOldQueryResults(query);
|
||||||
string keyword = query.ActionKeyword;
|
|
||||||
if (string.IsNullOrEmpty(lastKeyword))
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(keyword))
|
|
||||||
{
|
|
||||||
Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(keyword))
|
|
||||||
{
|
|
||||||
Results.RemoveResultsFor(PluginManager.NonGlobalPlugins[lastKeyword].Metadata);
|
|
||||||
}
|
|
||||||
else if (lastKeyword != keyword)
|
|
||||||
{
|
|
||||||
Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_lastQuery = query;
|
_lastQuery = query;
|
||||||
Task.Delay(200, _updateToken).ContinueWith(_ =>
|
Task.Delay(200, currentCancellationToken).ContinueWith(_ =>
|
||||||
{
|
{ // start the progress bar if query takes more than 200 ms and this is the current running query and it didn't finish yet
|
||||||
if (query.RawQuery == _lastQuery.RawQuery && !_queryHasReturn)
|
if (currentUpdateSource == _updateSource && _isQueryRunning)
|
||||||
{
|
{
|
||||||
ProgressBarVisibility = Visibility.Visible;
|
ProgressBarVisibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
}, _updateToken);
|
}, currentCancellationToken);
|
||||||
|
|
||||||
var plugins = PluginManager.ValidPluginsForQuery(query);
|
var plugins = PluginManager.ValidPluginsForQuery(query);
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
Parallel.ForEach(plugins, plugin =>
|
// so looping will stop once it was cancelled
|
||||||
|
var parallelOptions = new ParallelOptions { CancellationToken = currentCancellationToken };
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var config = _settings.PluginSettings.Plugins[plugin.Metadata.ID];
|
Parallel.ForEach(plugins, parallelOptions, plugin =>
|
||||||
if (!config.Disabled)
|
|
||||||
{
|
{
|
||||||
var results = PluginManager.QueryForPlugin(plugin, query);
|
var config = _settings.PluginSettings.Plugins[plugin.Metadata.ID];
|
||||||
UpdateResultView(results, plugin.Metadata, query);
|
if (!config.Disabled)
|
||||||
}
|
{
|
||||||
});
|
var results = PluginManager.QueryForPlugin(plugin, query);
|
||||||
|
UpdateResultView(results, plugin.Metadata, query);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// this should happen once after all queries are done so progress bar should continue
|
// this should happen once after all queries are done so progress bar should continue
|
||||||
// until the end of all querying
|
// until the end of all querying
|
||||||
_queryHasReturn = true;
|
_isQueryRunning = false;
|
||||||
ProgressBarVisibility = Visibility.Hidden;
|
if (currentUpdateSource == _updateSource)
|
||||||
}, _updateToken);
|
{ // update to hidden if this is still the current query
|
||||||
|
ProgressBarVisibility = Visibility.Hidden;
|
||||||
|
}
|
||||||
|
}, currentCancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -437,6 +432,30 @@ namespace Wox.ViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RemoveOldQueryResults(Query query)
|
||||||
|
{
|
||||||
|
string lastKeyword = _lastQuery.ActionKeyword;
|
||||||
|
string keyword = query.ActionKeyword;
|
||||||
|
if (string.IsNullOrEmpty(lastKeyword))
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(keyword))
|
||||||
|
{
|
||||||
|
Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(keyword))
|
||||||
|
{
|
||||||
|
Results.RemoveResultsFor(PluginManager.NonGlobalPlugins[lastKeyword].Metadata);
|
||||||
|
}
|
||||||
|
else if (lastKeyword != keyword)
|
||||||
|
{
|
||||||
|
Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private Result ContextMenuTopMost(Result result)
|
private Result ContextMenuTopMost(Result result)
|
||||||
{
|
{
|
||||||
|
|
@ -660,4 +679,4 @@ namespace Wox.ViewModel
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,7 +5,6 @@ namespace Wox.ViewModel
|
||||||
{
|
{
|
||||||
public class RelayCommand : ICommand
|
public class RelayCommand : ICommand
|
||||||
{
|
{
|
||||||
|
|
||||||
private Action<object> _action;
|
private Action<object> _action;
|
||||||
|
|
||||||
public RelayCommand(Action<object> action)
|
public RelayCommand(Action<object> action)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@ using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
using Wox.Infrastructure.UserSettings;
|
using Wox.Infrastructure.UserSettings;
|
||||||
using Wox.Plugin;
|
using Wox.Plugin;
|
||||||
|
|
||||||
|
|
@ -154,14 +156,14 @@ namespace Wox.ViewModel
|
||||||
private List<ResultViewModel> NewResults(List<Result> newRawResults, string resultId)
|
private List<ResultViewModel> NewResults(List<Result> newRawResults, string resultId)
|
||||||
{
|
{
|
||||||
var results = Results.ToList();
|
var results = Results.ToList();
|
||||||
var newResults = newRawResults.Select(r => new ResultViewModel(r)).ToList();
|
var newResults = newRawResults.Select(r => new ResultViewModel(r)).ToList();
|
||||||
var oldResults = results.Where(r => r.Result.PluginID == resultId).ToList();
|
var oldResults = results.Where(r => r.Result.PluginID == resultId).ToList();
|
||||||
|
|
||||||
// Find the same results in A (old results) and B (new newResults)
|
// Find the same results in A (old results) and B (new newResults)
|
||||||
var sameResults = oldResults
|
var sameResults = oldResults
|
||||||
.Where(t1 => newResults.Any(x => x.Result.Equals(t1.Result)))
|
.Where(t1 => newResults.Any(x => x.Result.Equals(t1.Result)))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// remove result of relative complement of B in A
|
// remove result of relative complement of B in A
|
||||||
foreach (var result in oldResults.Except(sameResults))
|
foreach (var result in oldResults.Except(sameResults))
|
||||||
{
|
{
|
||||||
|
|
@ -197,8 +199,37 @@ namespace Wox.ViewModel
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region FormattedText Dependency Property
|
||||||
|
public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached(
|
||||||
|
"FormattedText",
|
||||||
|
typeof(Inline),
|
||||||
|
typeof(ResultsViewModel),
|
||||||
|
new PropertyMetadata(null, FormattedTextPropertyChanged));
|
||||||
|
|
||||||
|
public static void SetFormattedText(DependencyObject textBlock, IList<int> value)
|
||||||
|
{
|
||||||
|
textBlock.SetValue(FormattedTextProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Inline GetFormattedText(DependencyObject textBlock)
|
||||||
|
{
|
||||||
|
return (Inline)textBlock.GetValue(FormattedTextProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FormattedTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBlock = d as TextBlock;
|
||||||
|
if (textBlock == null) return;
|
||||||
|
|
||||||
|
var inline = (Inline)e.NewValue;
|
||||||
|
|
||||||
|
textBlock.Inlines.Clear();
|
||||||
|
if (inline == null) return;
|
||||||
|
|
||||||
|
textBlock.Inlines.Add(inline);
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public class ResultCollection : ObservableCollection<ResultViewModel>
|
public class ResultCollection : ObservableCollection<ResultViewModel>
|
||||||
|
|
@ -217,6 +248,10 @@ namespace Wox.ViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the results collection with new results, try to keep identical results
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newItems"></param>
|
||||||
public void Update(List<ResultViewModel> newItems)
|
public void Update(List<ResultViewModel> newItems)
|
||||||
{
|
{
|
||||||
int newCount = newItems.Count;
|
int newCount = newItems.Count;
|
||||||
|
|
@ -228,7 +263,7 @@ namespace Wox.ViewModel
|
||||||
ResultViewModel oldResult = this[i];
|
ResultViewModel oldResult = this[i];
|
||||||
ResultViewModel newResult = newItems[i];
|
ResultViewModel newResult = newItems[i];
|
||||||
if (!oldResult.Equals(newResult))
|
if (!oldResult.Equals(newResult))
|
||||||
{
|
{ // result is not the same update it in the current index
|
||||||
this[i] = newResult;
|
this[i] = newResult;
|
||||||
}
|
}
|
||||||
else if (oldResult.Result.Score != newResult.Result.Score)
|
else if (oldResult.Result.Score != newResult.Result.Score)
|
||||||
|
|
@ -255,4 +290,4 @@ namespace Wox.ViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
@ -20,10 +21,12 @@ namespace Wox.ViewModel
|
||||||
{
|
{
|
||||||
public class SettingWindowViewModel : BaseModel
|
public class SettingWindowViewModel : BaseModel
|
||||||
{
|
{
|
||||||
|
private readonly Updater _updater;
|
||||||
private readonly WoxJsonStorage<Settings> _storage;
|
private readonly WoxJsonStorage<Settings> _storage;
|
||||||
|
|
||||||
public SettingWindowViewModel()
|
public SettingWindowViewModel(Updater updater)
|
||||||
{
|
{
|
||||||
|
_updater = updater;
|
||||||
_storage = new WoxJsonStorage<Settings>();
|
_storage = new WoxJsonStorage<Settings>();
|
||||||
Settings = _storage.Load();
|
Settings = _storage.Load();
|
||||||
Settings.PropertyChanged += (s, e) =>
|
Settings.PropertyChanged += (s, e) =>
|
||||||
|
|
@ -39,6 +42,10 @@ namespace Wox.ViewModel
|
||||||
|
|
||||||
public Settings Settings { get; set; }
|
public Settings Settings { get; set; }
|
||||||
|
|
||||||
|
public async void UpdateApp()
|
||||||
|
{
|
||||||
|
await _updater.UpdateApp();
|
||||||
|
}
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
|
|
@ -73,7 +80,7 @@ namespace Wox.ViewModel
|
||||||
public List<string> QuerySearchPrecisionStrings
|
public List<string> QuerySearchPrecisionStrings
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var precisionStrings = new List<string>();
|
var precisionStrings = new List<string>();
|
||||||
|
|
||||||
var enumList = Enum.GetValues(typeof(StringMatcher.SearchPrecisionScore)).Cast<StringMatcher.SearchPrecisionScore>().ToList();
|
var enumList = Enum.GetValues(typeof(StringMatcher.SearchPrecisionScore)).Cast<StringMatcher.SearchPrecisionScore>().ToList();
|
||||||
|
|
@ -88,6 +95,50 @@ namespace Wox.ViewModel
|
||||||
public List<Language> Languages => _translater.LoadAvailableLanguages();
|
public List<Language> Languages => _translater.LoadAvailableLanguages();
|
||||||
public IEnumerable<int> MaxResultsRange => Enumerable.Range(2, 16);
|
public IEnumerable<int> MaxResultsRange => Enumerable.Range(2, 16);
|
||||||
|
|
||||||
|
public string TestProxy()
|
||||||
|
{
|
||||||
|
var proxyServer = Settings.Proxy.Server;
|
||||||
|
var proxyUserName = Settings.Proxy.UserName;
|
||||||
|
if (string.IsNullOrEmpty(proxyServer))
|
||||||
|
{
|
||||||
|
return InternationalizationManager.Instance.GetTranslation("serverCantBeEmpty");
|
||||||
|
}
|
||||||
|
if (Settings.Proxy.Port <= 0)
|
||||||
|
{
|
||||||
|
return InternationalizationManager.Instance.GetTranslation("portCantBeEmpty");
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_updater.GitHubRepository);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(proxyUserName) || string.IsNullOrEmpty(Settings.Proxy.Password))
|
||||||
|
{
|
||||||
|
request.Proxy = new WebProxy(proxyServer, Settings.Proxy.Port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request.Proxy = new WebProxy(proxyServer, Settings.Proxy.Port)
|
||||||
|
{
|
||||||
|
Credentials = new NetworkCredential(proxyUserName, Settings.Proxy.Password)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = (HttpWebResponse)request.GetResponse();
|
||||||
|
if (response.StatusCode == HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
return InternationalizationManager.Instance.GetTranslation("proxyIsCorrect");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return InternationalizationManager.Instance.GetTranslation("proxyConnectFailed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return InternationalizationManager.Instance.GetTranslation("proxyConnectFailed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region plugin
|
#region plugin
|
||||||
|
|
@ -220,7 +271,7 @@ namespace Wox.ViewModel
|
||||||
},
|
},
|
||||||
new Result
|
new Result
|
||||||
{
|
{
|
||||||
Title = $"Open Source: {Constant.Repository}",
|
Title = $"Open Source: {_updater.GitHubRepository}",
|
||||||
SubTitle = "Please star it!"
|
SubTitle = "Please star it!"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -330,8 +381,8 @@ namespace Wox.ViewModel
|
||||||
|
|
||||||
#region about
|
#region about
|
||||||
|
|
||||||
public static string Github => Constant.Repository;
|
public string Github => _updater.GitHubRepository;
|
||||||
public static string ReleaseNotes => @"https://github.com/Wox-launcher/Wox/releases/latest";
|
public string ReleaseNotes => _updater.GitHubRepository + @"/releases/latest";
|
||||||
public static string Version => Constant.Version;
|
public static string Version => Constant.Version;
|
||||||
public string ActivatedTimes => string.Format(_translater.GetTranslation("about_activate_times"), Settings.ActivateTimes);
|
public string ActivatedTimes => string.Format(_translater.GetTranslation("about_activate_times"), Settings.ActivateTimes);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
||||||
119
Wox/Wox.csproj
119
Wox/Wox.csproj
|
|
@ -65,72 +65,8 @@
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="DeltaCompressionDotNet, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1d14d6e5194e7f4a, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="DeltaCompressionDotNet.MsDelta, Version=1.0.0.0, Culture=neutral, PublicKeyToken=46b2138a390abf55, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.MsDelta.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="DeltaCompressionDotNet.PatchApi, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3e8888ee913ed789, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.PatchApi.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\squirrel.windows.1.4.0\lib\Net45\ICSharpCode.SharpZipLib.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Mdb.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Pdb.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil.Rocks, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Rocks.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="NHotkey, Version=1.2.1.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\NHotkey.1.2.1\lib\net20\NHotkey.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="NHotkey.Wpf, Version=1.2.1.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\NHotkey.Wpf.1.2.1\lib\net35\NHotkey.Wpf.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\NLog.4.2.0\lib\net45\NLog.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="NuGet.Squirrel, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\squirrel.windows.1.4.0\lib\Net45\NuGet.Squirrel.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="PresentationUI, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
<Reference Include="PresentationUI, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||||
<Reference Include="PropertyChanged, Version=1.51.0.0, Culture=neutral, PublicKeyToken=ee3ee20bcf148ddd, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\PropertyChanged.Fody.1.51.0\lib\dotnet\PropertyChanged.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="ReachFramework" />
|
<Reference Include="ReachFramework" />
|
||||||
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Squirrel, Version=1.5.2.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\packages\squirrel.windows.1.5.2\lib\Net45\Squirrel.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Configuration" />
|
<Reference Include="System.Configuration" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
|
|
@ -149,21 +85,19 @@
|
||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="WindowsInput, Version=1.0.4.0, Culture=neutral, PublicKeyToken=9b287f7dc5073cad, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\InputSimulator.1.0.4.0\lib\net20\WindowsInput.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\SolutionAssemblyInfo.cs">
|
<Compile Include="..\SolutionAssemblyInfo.cs">
|
||||||
<Link>Properties\SolutionAssemblyInfo.cs</Link>
|
<Link>Properties\SolutionAssemblyInfo.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Converters\HighlightTextConverter.cs" />
|
||||||
<Compile Include="Helper\SingletonWindowOpener.cs" />
|
<Compile Include="Helper\SingletonWindowOpener.cs" />
|
||||||
<Compile Include="PublicAPIInstance.cs" />
|
<Compile Include="PublicAPIInstance.cs" />
|
||||||
<Compile Include="ReportWindow.xaml.cs" />
|
<Compile Include="ReportWindow.xaml.cs" />
|
||||||
<Compile Include="ResultListBox.xaml.cs">
|
<Compile Include="ResultListBox.xaml.cs">
|
||||||
<DependentUpon>ResultListBox.xaml</DependentUpon>
|
<DependentUpon>ResultListBox.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Settings.cs" />
|
||||||
<Compile Include="Storage\HistoryItem.cs" />
|
<Compile Include="Storage\HistoryItem.cs" />
|
||||||
<Compile Include="Storage\QueryHistory.cs" />
|
<Compile Include="Storage\QueryHistory.cs" />
|
||||||
<Compile Include="Storage\TopMostRecord.cs" />
|
<Compile Include="Storage\TopMostRecord.cs" />
|
||||||
|
|
@ -346,9 +280,6 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<None Include="packages.config">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
</None>
|
|
||||||
<None Include="Themes\Light.xaml">
|
<None Include="Themes\Light.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
|
@ -469,7 +400,44 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Resource>
|
</Resource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Fody">
|
||||||
|
<Version>1.29.2</Version>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="InputSimulator">
|
||||||
|
<Version>1.0.4</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="JetBrains.Annotations">
|
||||||
|
<Version>10.3.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>9.0.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NHotkey.Wpf">
|
||||||
|
<Version>1.2.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NLog">
|
||||||
|
<Version>4.2.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NuGet.CommandLine">
|
||||||
|
<Version>3.4.3</Version>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="PropertyChanged.Fody">
|
||||||
|
<Version>1.51.0</Version>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="squirrel.windows">
|
||||||
|
<Version>1.5.2</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Runtime">
|
||||||
|
<Version>4.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>powershell.exe -NoProfile -ExecutionPolicy Bypass -File $(SolutionDir)Scripts\post_build.ps1 $(ConfigurationName) $(SolutionDir)</PostBuildEvent>
|
<PostBuildEvent>powershell.exe -NoProfile -ExecutionPolicy Bypass -File $(SolutionDir)Scripts\post_build.ps1 $(ConfigurationName) $(SolutionDir)</PostBuildEvent>
|
||||||
|
|
@ -484,11 +452,4 @@
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
<Import Project="..\packages\Fody.1.29.2\build\dotnet\Fody.targets" Condition="Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" />
|
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Error Condition="!Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.29.2\build\dotnet\Fody.targets'))" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="DeltaCompressionDotNet" version="1.0.0" targetFramework="net452" />
|
|
||||||
<package id="Fody" version="1.29.2" targetFramework="net452" developmentDependency="true" />
|
|
||||||
<package id="InputSimulator" version="1.0.4.0" targetFramework="net452" />
|
|
||||||
<package id="JetBrains.Annotations" version="10.3.0" targetFramework="net452" />
|
|
||||||
<package id="Mono.Cecil" version="0.9.6.1" targetFramework="net452" />
|
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
|
||||||
<package id="NHotkey" version="1.2.1" targetFramework="net452" />
|
|
||||||
<package id="NHotkey.Wpf" version="1.2.1" targetFramework="net452" />
|
|
||||||
<package id="NLog" version="4.2.0" targetFramework="net452" />
|
|
||||||
<package id="NuGet.CommandLine" version="3.4.3" targetFramework="net452" developmentDependency="true" />
|
|
||||||
<package id="PropertyChanged.Fody" version="1.51.0" targetFramework="net452" developmentDependency="true" />
|
|
||||||
<package id="SharpZipLib" version="0.86.0" targetFramework="net452" />
|
|
||||||
<package id="Splat" version="1.6.2" targetFramework="net452" />
|
|
||||||
<package id="squirrel.windows" version="1.5.2" targetFramework="net452" />
|
|
||||||
<package id="System.Runtime" version="4.0.0" targetFramework="net452" />
|
|
||||||
</packages>
|
|
||||||
34
azure-pipelines.yml
Normal file
34
azure-pipelines.yml
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
# .NET Desktop
|
||||||
|
# Build and run tests for .NET Desktop or Windows classic desktop solutions.
|
||||||
|
# Add steps that publish symbols, save build artifacts, and more:
|
||||||
|
# https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- master
|
||||||
|
- dev
|
||||||
|
|
||||||
|
pool:
|
||||||
|
vmImage: 'vs2017-win2016' #'due to windows SDK dependency for building UWP project'
|
||||||
|
|
||||||
|
variables:
|
||||||
|
solution: '**/*.sln'
|
||||||
|
buildPlatform: 'Any CPU'
|
||||||
|
buildConfiguration: 'Release'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- task: NuGetToolInstaller@1
|
||||||
|
|
||||||
|
- task: NuGetCommand@2
|
||||||
|
inputs:
|
||||||
|
restoreSolution: '$(solution)'
|
||||||
|
|
||||||
|
- task: VSBuild@1
|
||||||
|
inputs:
|
||||||
|
solution: '$(solution)'
|
||||||
|
platform: '$(buildPlatform)'
|
||||||
|
configuration: '$(buildConfiguration)'
|
||||||
|
|
||||||
|
- task: VSTest@2
|
||||||
|
inputs:
|
||||||
|
platform: '$(buildPlatform)'
|
||||||
|
configuration: '$(buildConfiguration)'
|
||||||
Loading…
Reference in a new issue