mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-14 19:49:15 +08:00
Merge branch 'upstreamdev' into queryPluginsUpdates
This commit is contained in:
commit
be77bf94aa
@ -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");
|
||||||
|
@ -55,6 +55,7 @@ namespace Wox.Plugin.Everything
|
|||||||
r.Title = Path.GetFileName(path);
|
r.Title = Path.GetFileName(path);
|
||||||
r.SubTitle = path;
|
r.SubTitle = path;
|
||||||
r.IcoPath = path;
|
r.IcoPath = path;
|
||||||
|
r.TitleHighlightData = StringMatcher.FuzzySearch(keyword, Path.GetFileName(path)).MatchData;
|
||||||
r.Action = c =>
|
r.Action = c =>
|
||||||
{
|
{
|
||||||
bool hide;
|
bool hide;
|
||||||
@ -78,6 +79,7 @@ namespace Wox.Plugin.Everything
|
|||||||
return hide;
|
return hide;
|
||||||
};
|
};
|
||||||
r.ContextData = s;
|
r.ContextData = s;
|
||||||
|
r.SubTitleHighlightData = StringMatcher.FuzzySearch(keyword, path).MatchData;
|
||||||
results.Add(r);
|
results.Add(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ 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
|
||||||
@ -58,13 +59,14 @@ namespace Wox.Plugin.Folder
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result CreateFolderResult(string title, string path, string queryActionKeyword)
|
private Result CreateFolderResult(string title, 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 = "Ctrl + Enter to open the directory",
|
||||||
|
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
if (c.SpecialKeyState.CtrlPressed)
|
if (c.SpecialKeyState.CtrlPressed)
|
||||||
@ -82,7 +84,9 @@ 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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -93,8 +97,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, item.Path, query)).ToList();
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,34 +136,40 @@ 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);
|
incompleteName = incompleteName.Substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -168,12 +178,12 @@ namespace Wox.Plugin.Folder
|
|||||||
|
|
||||||
var result =
|
var result =
|
||||||
fileSystemInfo is DirectoryInfo
|
fileSystemInfo is DirectoryInfo
|
||||||
? CreateFolderResult(fileSystemInfo.Name, fileSystemInfo.FullName, query.ActionKeyword)
|
? CreateFolderResult(fileSystemInfo.Name, fileSystemInfo.FullName, query)
|
||||||
: CreateFileResult(fileSystemInfo.FullName);
|
: CreateFileResult(fileSystemInfo.FullName, query);
|
||||||
results.Add(result);
|
results.Add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (e is UnauthorizedAccessException || e is ArgumentException)
|
if (e is UnauthorizedAccessException || e is ArgumentException)
|
||||||
{
|
{
|
||||||
@ -188,12 +198,13 @@ namespace Wox.Plugin.Folder
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
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),
|
||||||
IcoPath = filePath,
|
IcoPath = filePath,
|
||||||
|
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, Path.GetFileName(filePath)).MatchData,
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -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);
|
||||||
|
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,12 +191,12 @@ namespace Wox.Plugin.Program
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool StartProcess(ProcessStartInfo info)
|
public static bool StartProcess(Func<ProcessStartInfo, Process> runProcess, ProcessStartInfo info)
|
||||||
{
|
{
|
||||||
bool hide;
|
bool hide;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Process.Start(info);
|
runProcess(info);
|
||||||
hide = true;
|
hide = true;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
@ -320,7 +321,7 @@ 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(Package.Location));
|
var hide = Main.StartProcess(Process.Start, new ProcessStartInfo(Package.Location));
|
||||||
return hide;
|
return hide;
|
||||||
},
|
},
|
||||||
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,7 +64,7 @@ namespace Wox.Plugin.Program.Programs
|
|||||||
FileName = FullPath,
|
FileName = FullPath,
|
||||||
WorkingDirectory = ParentDirectory
|
WorkingDirectory = ParentDirectory
|
||||||
};
|
};
|
||||||
var hide = Main.StartProcess(info);
|
var hide = Main.StartProcess(Process.Start, info);
|
||||||
return hide;
|
return hide;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -73,14 +73,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 +95,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,7 +119,7 @@ namespace Wox.Plugin.Program.Programs
|
|||||||
WorkingDirectory = ParentDirectory,
|
WorkingDirectory = ParentDirectory,
|
||||||
Verb = "runas"
|
Verb = "runas"
|
||||||
};
|
};
|
||||||
var hide = Main.StartProcess(info);
|
var hide = Main.StartProcess(Process.Start, info);
|
||||||
return hide;
|
return hide;
|
||||||
},
|
},
|
||||||
IcoPath = "Images/cmd.png"
|
IcoPath = "Images/cmd.png"
|
||||||
@ -112,7 +129,7 @@ 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));
|
var hide = Main.StartProcess(Process.Start, new ProcessStartInfo(ParentDirectory));
|
||||||
return hide;
|
return hide;
|
||||||
},
|
},
|
||||||
IcoPath = "Images/folder.png"
|
IcoPath = "Images/folder.png"
|
||||||
|
@ -112,6 +112,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>
|
||||||
|
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 |
@ -5,6 +5,7 @@
|
|||||||
<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_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,8 +1,10 @@
|
|||||||
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;
|
||||||
@ -84,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;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@ -117,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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -136,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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -154,14 +156,14 @@ 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);
|
||||||
@ -212,19 +214,33 @@ namespace Wox.Plugin.Shell
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return;
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
info.UseShellExecute = true;
|
info.UseShellExecute = true;
|
||||||
|
|
||||||
|
_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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,16 +16,22 @@ namespace Wox.Infrastructure
|
|||||||
private static ConcurrentDictionary<string, string[][]> PinyinCache;
|
private static ConcurrentDictionary<string, string[][]> PinyinCache;
|
||||||
private static BinaryStorage<ConcurrentDictionary<string, string[][]>> _pinyinStorage;
|
private static BinaryStorage<ConcurrentDictionary<string, string[][]>> _pinyinStorage;
|
||||||
private static Settings _settings;
|
private static Settings _settings;
|
||||||
|
|
||||||
public static void Initialize(Settings settings)
|
public static void Initialize(Settings settings)
|
||||||
{
|
{
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
InitializePinyinHelpers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void InitializePinyinHelpers()
|
||||||
|
{
|
||||||
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);
|
||||||
});
|
});
|
||||||
@ -34,6 +40,10 @@ namespace Wox.Infrastructure
|
|||||||
|
|
||||||
public static void Save()
|
public static void Save()
|
||||||
{
|
{
|
||||||
|
if (!_settings.ShouldUsePinyin)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
_pinyinStorage.Save(PinyinCache);
|
_pinyinStorage.Save(PinyinCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,39 +78,36 @@ namespace Wox.Infrastructure
|
|||||||
/// </summmary>
|
/// </summmary>
|
||||||
public static string[][] PinyinComination(string characters)
|
public static string[][] PinyinComination(string characters)
|
||||||
{
|
{
|
||||||
if (_settings.ShouldUsePinyin && !string.IsNullOrEmpty(characters))
|
if (!_settings.ShouldUsePinyin || string.IsNullOrEmpty(characters))
|
||||||
{
|
{
|
||||||
if (!PinyinCache.ContainsKey(characters))
|
return Empty2DStringArray;
|
||||||
{
|
}
|
||||||
|
|
||||||
var allPinyins = new List<string[]>();
|
if (!PinyinCache.ContainsKey(characters))
|
||||||
foreach (var c in characters)
|
{
|
||||||
|
var allPinyins = new List<string[]>();
|
||||||
|
foreach (var c in characters)
|
||||||
|
{
|
||||||
|
var pinyins = PinyinHelper.toHanyuPinyinStringArray(c, Format);
|
||||||
|
if (pinyins != null)
|
||||||
{
|
{
|
||||||
var pinyins = PinyinHelper.toHanyuPinyinStringArray(c, Format);
|
var r = pinyins.Distinct().ToArray();
|
||||||
if (pinyins != null)
|
allPinyins.Add(r);
|
||||||
{
|
|
||||||
var r = pinyins.Distinct().ToArray();
|
|
||||||
allPinyins.Add(r);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var r = new[] { c.ToString() };
|
|
||||||
allPinyins.Add(r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var r = new[] { c.ToString() };
|
||||||
|
allPinyins.Add(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var combination = allPinyins.Aggregate(Combination).Select(c => c.Split(';')).ToArray();
|
var combination = allPinyins.Aggregate(Combination).Select(c => c.Split(';')).ToArray();
|
||||||
PinyinCache[characters] = combination;
|
PinyinCache[characters] = combination;
|
||||||
return combination;
|
return combination;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return PinyinCache[characters];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return Empty2DStringArray;
|
return PinyinCache[characters];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +149,5 @@ namespace Wox.Infrastructure
|
|||||||
).ToArray();
|
).ToArray();
|
||||||
return combination;
|
return combination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Wox.Infrastructure.Logger;
|
using Wox.Infrastructure.Logger;
|
||||||
using Wox.Infrastructure.UserSettings;
|
using Wox.Infrastructure.UserSettings;
|
||||||
|
using static Wox.Infrastructure.StringMatcher;
|
||||||
|
|
||||||
namespace Wox.Infrastructure
|
namespace Wox.Infrastructure
|
||||||
{
|
{
|
||||||
public static class StringMatcher
|
public static class StringMatcher
|
||||||
{
|
{
|
||||||
public static MatchOption DefaultMatchOption = new MatchOption();
|
public static MatchOption DefaultMatchOption = new MatchOption();
|
||||||
|
|
||||||
public static string UserSettingSearchPrecision { get; set; }
|
public static string UserSettingSearchPrecision { get; set; }
|
||||||
|
public static bool ShouldUsePinyin { get; 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)
|
||||||
@ -54,6 +57,9 @@ namespace Wox.Infrastructure
|
|||||||
var firstMatchIndex = -1;
|
var firstMatchIndex = -1;
|
||||||
var lastMatchIndex = 0;
|
var lastMatchIndex = 0;
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
|
var indexList = new List<int>();
|
||||||
|
|
||||||
for (var idx = 0; idx < len; idx++)
|
for (var idx = 0; idx < len; idx++)
|
||||||
{
|
{
|
||||||
ch = stringToCompare[idx];
|
ch = stringToCompare[idx];
|
||||||
@ -63,6 +69,7 @@ namespace Wox.Infrastructure
|
|||||||
firstMatchIndex = idx;
|
firstMatchIndex = idx;
|
||||||
lastMatchIndex = idx + 1;
|
lastMatchIndex = idx + 1;
|
||||||
|
|
||||||
|
indexList.Add(idx);
|
||||||
sb.Append(opt.Prefix + ch + opt.Suffix);
|
sb.Append(opt.Prefix + ch + opt.Suffix);
|
||||||
patternIdx += 1;
|
patternIdx += 1;
|
||||||
}
|
}
|
||||||
@ -82,27 +89,38 @@ namespace Wox.Infrastructure
|
|||||||
// return rendered string if we have a match for every char
|
// return rendered string if we have a match for every char
|
||||||
if (patternIdx == pattern.Length)
|
if (patternIdx == pattern.Length)
|
||||||
{
|
{
|
||||||
return new MatchResult
|
var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex, lastMatchIndex - firstMatchIndex);
|
||||||
|
var pinyinScore = ScoreForPinyin(stringToCompare, query);
|
||||||
|
|
||||||
|
var result = new MatchResult
|
||||||
{
|
{
|
||||||
Success = true,
|
Success = true,
|
||||||
Value = sb.ToString(),
|
MatchData = indexList,
|
||||||
Score = CalScore(query, stringToCompare, firstMatchIndex, lastMatchIndex - firstMatchIndex)
|
RawScore = Math.Max(score, pinyinScore)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MatchResult { Success = false };
|
return new MatchResult { Success = false };
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int CalScore(string query, string stringToCompare, int firstIndex, int matchLen)
|
private static int CalculateSearchScore(string query, string stringToCompare, int firstIndex, int matchLen)
|
||||||
{
|
{
|
||||||
//a match found near the beginning of a string is scored more than a match found near the end
|
// 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
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
@ -114,21 +132,13 @@ namespace Wox.Infrastructure
|
|||||||
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)
|
public static int ScoreForPinyin(string source, string target)
|
||||||
{
|
{
|
||||||
|
if (!ShouldUsePinyin)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(target))
|
if (!string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(target))
|
||||||
{
|
{
|
||||||
if (Alphabet.ContainsChinese(source))
|
if (Alphabet.ContainsChinese(source))
|
||||||
@ -158,12 +168,48 @@ namespace Wox.Infrastructure
|
|||||||
public class MatchResult
|
public class MatchResult
|
||||||
{
|
{
|
||||||
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 all 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 = ApplySearchPrecisionFilter(_rawScore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Matched data to highlight.
|
||||||
|
/// </summary>
|
||||||
|
public List<int> MatchData { get; set; }
|
||||||
|
|
||||||
|
public bool IsSearchPrecisionScoreMet()
|
||||||
|
{
|
||||||
|
return IsSearchPrecisionScoreMet(Score);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsSearchPrecisionScoreMet(int score)
|
||||||
|
{
|
||||||
|
var precisionScore = (SearchPrecisionScore)Enum.Parse(
|
||||||
|
typeof(SearchPrecisionScore),
|
||||||
|
UserSettingSearchPrecision ?? SearchPrecisionScore.Regular.ToString());
|
||||||
|
return score >= (int)precisionScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ApplySearchPrecisionFilter(int score)
|
||||||
|
{
|
||||||
|
return IsSearchPrecisionScoreMet(score) ? score : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MatchOption
|
public class MatchOption
|
||||||
|
@ -24,7 +24,17 @@ namespace Wox.Infrastructure.UserSettings
|
|||||||
/// <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;
|
private bool _shouldUsePinyin = true;
|
||||||
|
public bool ShouldUsePinyin
|
||||||
|
{
|
||||||
|
get { return _shouldUsePinyin; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_shouldUsePinyin = value;
|
||||||
|
StringMatcher.ShouldUsePinyin = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private string _querySearchPrecision { get; set; } = StringMatcher.SearchPrecisionScore.Regular.ToString();
|
private string _querySearchPrecision { get; set; } = StringMatcher.SearchPrecisionScore.Regular.ToString();
|
||||||
public string QuerySearchPrecision
|
public string QuerySearchPrecision
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,65 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Wox.Plugin.SharedCommands
|
namespace Wox.Plugin.SharedCommands
|
||||||
{
|
{
|
||||||
public static class ShellCommand
|
public static class ShellCommand
|
||||||
{
|
{
|
||||||
public static ProcessStartInfo SetProcessStartInfo(this string fileName, string workingDirectory="", string arguments = "", string verb = "")
|
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
|
var info = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Wox.Infrastructure;
|
using Wox.Infrastructure;
|
||||||
|
using Wox.Infrastructure.UserSettings;
|
||||||
using Wox.Plugin;
|
using Wox.Plugin;
|
||||||
|
|
||||||
namespace Wox.Test
|
namespace Wox.Test
|
||||||
@ -11,7 +12,7 @@ namespace Wox.Test
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class FuzzyMatcherTest
|
public class FuzzyMatcherTest
|
||||||
{
|
{
|
||||||
public List<string> GetSearchStrings()
|
public List<string> GetSearchStrings()
|
||||||
=> new List<string>
|
=> new List<string>
|
||||||
{
|
{
|
||||||
"Chrome",
|
"Chrome",
|
||||||
@ -48,14 +49,13 @@ namespace Wox.Test
|
|||||||
"aac"
|
"aac"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var results = new List<Result>();
|
var results = new List<Result>();
|
||||||
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 = StringMatcher.FuzzySearch("inst", str).RawScore
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ namespace Wox.Test
|
|||||||
{
|
{
|
||||||
var compareString = "Can have rum only in my glass";
|
var compareString = "Can have rum only in my glass";
|
||||||
|
|
||||||
var scoreResult = StringMatcher.FuzzySearch(searchString, compareString).Score;
|
var scoreResult = StringMatcher.FuzzySearch(searchString, compareString).RawScore;
|
||||||
|
|
||||||
Assert.True(scoreResult == 0);
|
Assert.True(scoreResult == 0);
|
||||||
}
|
}
|
||||||
@ -129,13 +129,12 @@ namespace Wox.Test
|
|||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var results = new List<Result>();
|
var results = new List<Result>();
|
||||||
|
|
||||||
foreach (var str in searchStrings)
|
foreach (var str in searchStrings)
|
||||||
{
|
{
|
||||||
results.Add(new Result
|
results.Add(new Result
|
||||||
{
|
{
|
||||||
Title = str,
|
Title = str,
|
||||||
Score = StringMatcher.FuzzySearch(searchTerm, str).Score
|
Score = StringMatcher.FuzzySearch(searchTerm, str).RawScore
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,8 +167,11 @@ namespace Wox.Test
|
|||||||
[TestCase("ccs", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.Low, true)]
|
[TestCase("ccs", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.Low, true)]
|
||||||
[TestCase("cand", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.Regular, true)]
|
[TestCase("cand", "Candy Crush Saga from King", (int)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", (int)StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||||
public void WhenGivenDesiredPrecisionThenShouldReturnAllResultsGreaterOrEqual(string queryString, string compareString,
|
public void WhenGivenDesiredPrecisionThenShouldReturnAllResultsGreaterOrEqual(
|
||||||
int expectedPrecisionScore, bool expectedPrecisionResult)
|
string queryString,
|
||||||
|
string compareString,
|
||||||
|
int expectedPrecisionScore,
|
||||||
|
bool expectedPrecisionResult)
|
||||||
{
|
{
|
||||||
var expectedPrecisionString = (StringMatcher.SearchPrecisionScore)expectedPrecisionScore;
|
var expectedPrecisionString = (StringMatcher.SearchPrecisionScore)expectedPrecisionScore;
|
||||||
StringMatcher.UserSettingSearchPrecision = expectedPrecisionString.ToString();
|
StringMatcher.UserSettingSearchPrecision = expectedPrecisionString.ToString();
|
||||||
|
@ -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;
|
||||||
@ -56,6 +56,7 @@ namespace Wox
|
|||||||
Alphabet.Initialize(_settings);
|
Alphabet.Initialize(_settings);
|
||||||
|
|
||||||
StringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
|
StringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
|
||||||
|
StringMatcher.ShouldUsePinyin = _settings.ShouldUsePinyin;
|
||||||
|
|
||||||
PluginManager.LoadPlugins(_settings.PluginSettings);
|
PluginManager.LoadPlugins(_settings.PluginSettings);
|
||||||
_mainVM = new MainViewModel(_settings);
|
_mainVM = new MainViewModel(_settings);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
|
||||||
@ -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>
|
||||||
|
@ -158,6 +158,7 @@
|
|||||||
<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" />
|
||||||
|
Loading…
Reference in New Issue
Block a user