Rename Wox.Plugin.System to Wox.Plugin.SystemPlugins

Finish moving ProgramSetting into featureBox
This commit is contained in:
Yeechan Lu
2014-03-29 15:52:57 +08:00
parent 479945455b
commit 80ec16b9bd
35 changed files with 142 additions and 51 deletions

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Wox.Plugin.SystemPlugins
{
public abstract class BaseSystemPlugin :ISystemPlugin
{
protected abstract List<Result> QueryInternal(Query query);
protected abstract void InitInternal(PluginInitContext context);
public List<Result> Query(Query query)
{
if (string.IsNullOrEmpty(query.RawQuery)) return new List<Result>();
return QueryInternal(query);
}
public void Init(PluginInitContext context)
{
InitInternal(context);
}
public virtual string Name
{
get
{
return "System workflow";
}
}
public virtual string Description
{
get
{
return "System workflow";
}
}
public virtual string IcoPath
{
get
{
return null;
}
}
public string PluginDirectory { get; set; }
}
}

View File

@@ -0,0 +1,187 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Newtonsoft.Json;
using Wox.Infrastructure;
namespace Wox.Plugin.SystemPlugins
{
public class BrowserBookmarks : BaseSystemPlugin
{
private PluginInitContext context;
private List<Bookmark> bookmarks = new List<Bookmark>();
protected override List<Result> QueryInternal(Query query)
{
if (string.IsNullOrEmpty(query.RawQuery) || query.RawQuery.EndsWith(" ") || query.RawQuery.Length <= 1) return new List<Result>();
var fuzzyMather = FuzzyMatcher.Create(query.RawQuery);
List<Bookmark> returnList = bookmarks.Where(o => MatchProgram(o, fuzzyMather)).ToList();
returnList = returnList.OrderByDescending(o => o.Score).ToList();
return returnList.Select(c => new Result()
{
Title = c.Name,
SubTitle = "Bookmark: " + c.Url,
IcoPath = Path.GetDirectoryName(Application.ExecutablePath) + @"\Images\bookmark.png",
Score = 5,
Action = (e) =>
{
context.HideApp();
context.ShellRun(c.Url);
return true;
}
}).ToList();
}
private bool MatchProgram(Bookmark bookmark, FuzzyMatcher matcher)
{
if ((bookmark.Score = matcher.Evaluate(bookmark.Name).Score) > 0) return true;
if ((bookmark.Score = matcher.Evaluate(bookmark.PinyinName).Score) > 0) return true;
if ((bookmark.Score = matcher.Evaluate(bookmark.Url).Score / 10) > 0) return true;
return false;
}
protected override void InitInternal(PluginInitContext context)
{
bookmarks.Clear();
LoadChromeBookmarks();
bookmarks = bookmarks.Distinct().ToList();
this.context = context;
}
private void ParseChromeBookmarks(String path, string source)
{
if (!File.Exists(path)) return;
string all = File.ReadAllText(path);
Regex nameRegex = new Regex("\"name\": \"(?<name>.*?)\"");
MatchCollection nameCollection = nameRegex.Matches(all);
Regex typeRegex = new Regex("\"type\": \"(?<type>.*?)\"");
MatchCollection typeCollection = typeRegex.Matches(all);
Regex urlRegex = new Regex("\"url\": \"(?<url>.*?)\"");
MatchCollection urlCollection = urlRegex.Matches(all);
List<string> names = (from Match match in nameCollection select match.Groups["name"].Value).ToList();
List<string> types = (from Match match in typeCollection select match.Groups["type"].Value).ToList();
List<string> urls = (from Match match in urlCollection select match.Groups["url"].Value).ToList();
int urlIndex = 0;
for (int i = 0; i < names.Count; i++)
{
string name = DecodeUnicode(names[i]);
string type = types[i];
if (type == "url")
{
string url = urls[urlIndex];
urlIndex++;
if (url == null) continue;
if (url.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase)) continue;
if (url.StartsWith("vbscript:", StringComparison.OrdinalIgnoreCase)) continue;
bookmarks.Add(new Bookmark()
{
Name = name,
Url = url,
Source = source
});
}
}
}
private void LoadChromeBookmarks(string path, string name)
{
if (!Directory.Exists(path)) return;
var paths = Directory.GetDirectories(path);
foreach (var profile in paths)
{
if (File.Exists(Path.Combine(profile, "Bookmarks")))
ParseChromeBookmarks(Path.Combine(profile, "Bookmarks"), name + (Path.GetFileName(profile) == "Default" ? "" : (" (" + Path.GetFileName(profile) + ")")));
}
}
private void LoadChromeBookmarks()
{
String platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
LoadChromeBookmarks(Path.Combine(platformPath, @"Google\Chrome\User Data"), "Google Chrome");
LoadChromeBookmarks(Path.Combine(platformPath, @"Google\Chrome SxS\User Data"), "Google Chrome Canary");
LoadChromeBookmarks(Path.Combine(platformPath, @"Chromium\User Data"), "Chromium");
}
private String DecodeUnicode(String dataStr)
{
Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})");
return reg.Replace(dataStr, m => ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString());
}
public override string Name
{
get { return "Bookmarks"; }
}
public override string IcoPath
{
get { return @"Images\bookmark.png"; }
}
public override string Description
{
get { return base.Description; }
}
}
public class Bookmark : IEquatable<Bookmark>, IEqualityComparer<Bookmark>
{
private string m_Name;
public string Name {
get{
return m_Name;
}
set
{
m_Name = value;
PinyinName = ChineseToPinYin.ToPinYin(m_Name).Replace(" ", "").ToLower();
}
}
public string PinyinName { get; private set; }
public string Url { get; set; }
public string Source { get; set; }
public int Score { get; set; }
/* TODO: since Source maybe unimportant, we just need to compare Name and Url */
public bool Equals(Bookmark other)
{
return Equals(this, other);
}
public bool Equals(Bookmark x, Bookmark y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x.Name == y.Name && x.Url == y.Url;
}
public int GetHashCode(Bookmark bookmark)
{
if (Object.ReferenceEquals(bookmark, null)) return 0;
int hashName = bookmark.Name == null ? 0 : bookmark.Name.GetHashCode();
int hashUrl = bookmark.Url == null ? 0 : bookmark.Url.GetHashCode();
return hashName ^ hashUrl;
}
public override int GetHashCode()
{
return GetHashCode(this);
}
}
}

View File

@@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
namespace Wox.Plugin.SystemPlugins.CMD
{
public class CMD : BaseSystemPlugin
{
private PluginInitContext context;
protected override List<Result> QueryInternal(Query query)
{
List<Result> results = new List<Result>();
List<Result> pushedResults = new List<Result>();
if (query.RawQuery == ">")
{
IEnumerable<Result> history = CMDStorage.Instance.CMDHistory.OrderByDescending(o => o.Value)
.Select(m => new Result
{
Title = m.Key,
SubTitle = "this command has been executed " + m.Value + " times",
IcoPath = "Images/cmd.png",
Action = (c) =>
{
ExecuteCmd(m.Key);
return true;
}
}).Take(5);
results.AddRange(history);
}
if (query.RawQuery.StartsWith(">") && query.RawQuery.Length > 1)
{
string cmd = query.RawQuery.Substring(1);
Result result = new Result
{
Title = cmd,
Score = 5000,
SubTitle = "execute command through command shell",
IcoPath = "Images/cmd.png",
Action = (c) =>
{
ExecuteCmd(cmd);
return true;
}
};
try
{
if (File.Exists(cmd) || Directory.Exists(cmd))
{
result.IcoPath = cmd;
}
}
catch (Exception) { }
context.PushResults(query, new List<Result>() { result });
pushedResults.Add(result);
IEnumerable<Result> history = CMDStorage.Instance.CMDHistory.Where(o => o.Key.Contains(cmd))
.OrderByDescending(o => o.Value)
.Select(m =>
{
if (m.Key == cmd)
{
result.SubTitle = "this command has been executed " + m.Value + " times";
return null;
}
var ret = new Result
{
Title = m.Key,
SubTitle = "this command has been executed " + m.Value + " times",
IcoPath = "Images/cmd.png",
Action = (c) =>
{
ExecuteCmd(m.Key);
return true;
}
};
try
{
if (File.Exists(m.Key) || Directory.Exists(m.Key))
{
ret.IcoPath = m.Key;
}
}
catch (Exception) { }
return ret;
}).Where(o => o != null).Take(4);
context.PushResults(query, history.ToList());
pushedResults.AddRange(history);
try
{
string basedir = null;
string dir = null;
string excmd = Environment.ExpandEnvironmentVariables(cmd);
if (Directory.Exists(excmd) && (cmd.EndsWith("/") || cmd.EndsWith(@"\")))
{
basedir = excmd;
dir = cmd;
}
else if (Directory.Exists(Path.GetDirectoryName(excmd)))
{
basedir = Path.GetDirectoryName(excmd);
var dirn = Path.GetDirectoryName(cmd);
dir = (dirn.EndsWith("/") || dirn.EndsWith(@"\")) ? dirn : cmd.Substring(0, dirn.Length + 1);
}
if (basedir != null)
{
List<string> autocomplete = Directory.GetFileSystemEntries(basedir).Select(o => dir + Path.GetFileName(o)).Where(o => o.StartsWith(cmd, StringComparison.OrdinalIgnoreCase) && !results.Any(p => o.Equals(p.Title, StringComparison.OrdinalIgnoreCase)) && !pushedResults.Any(p => o.Equals(p.Title, StringComparison.OrdinalIgnoreCase))).ToList();
autocomplete.Sort();
results.AddRange(autocomplete.ConvertAll(m => new Result()
{
Title = m,
SubTitle = "",
IcoPath = m,
Action = (c) =>
{
ExecuteCmd(m);
return true;
}
}));
}
}
catch (Exception) { }
}
return results;
}
private void ExecuteCmd(string cmd)
{
if (context.ShellRun(cmd))
CMDStorage.Instance.AddCmdHistory(cmd);
}
protected override void InitInternal(PluginInitContext context)
{
this.context = context;
}
public override string Name
{
get { return "Shell"; }
}
public override string IcoPath
{
get { return @"Images\cmd.png"; }
}
public override string Description
{
get { return base.Description; }
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Wox.Infrastructure.Storage;
namespace Wox.Plugin.SystemPlugins.CMD
{
public class CMDStorage : BaseStorage<CMDStorage>
{
[JsonProperty]
public Dictionary<string, int> CMDHistory = new Dictionary<string, int>();
protected override string ConfigName
{
get { return "CMDHistory"; }
}
public void AddCmdHistory(string cmdName)
{
if (CMDHistory.ContainsKey(cmdName))
{
CMDHistory[cmdName] += 1;
}
else
{
CMDHistory.Add(cmdName, 1);
}
Save();
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using YAMP;
namespace Wox.Plugin.SystemPlugins
{
public class Calculator : BaseSystemPlugin
{
private static Regex regValidExpressChar = new Regex(
@"^(" +
@"sin|cos|ceil|floor|exp|pi|max|min|det|arccos|abs|" +
@"eigval|eigvec|eig|sum|polar|plot|round|sort|real|zeta|" +
@"bin2dec|hex2dec|oct2dec|" +
@"==|~=|&&|\|\||" +
@"[ei]|[0-9]|[\+\-\*\/\^\., ""]|[\(\)\|\!\[\]]" +
@")+$", RegexOptions.Compiled);
private static Regex regBrackets = new Regex(@"[\(\)\[\]]", RegexOptions.Compiled);
private static ParseContext yampContext = null;
private PluginInitContext context { get; set; }
static Calculator()
{
yampContext = Parser.PrimaryContext;
Parser.InteractiveMode = false;
Parser.UseScripting = false;
}
protected override List<Result> QueryInternal(Query query)
{
if (string.IsNullOrEmpty(query.RawQuery)
|| query.RawQuery.Length <= 2 // don't affect when user only input "e" or "i" keyword
|| !regValidExpressChar.IsMatch(query.RawQuery)
|| !IsBracketComplete(query.RawQuery)) return new List<Result>();
try
{
var result = yampContext.Run(query.RawQuery);
if (result.Output != null && !string.IsNullOrEmpty(result.Result))
{
return new List<Result>() { new Result() {
Title = result.Result,
IcoPath = "Images/calculator.png",
Score = 300,
SubTitle = "Copy this number to the clipboard",
Action = (c) =>
{
Clipboard.SetText(result.Result);
return true;
}
} };
}
}
catch
{}
return new List<Result>();
}
private bool IsBracketComplete(string query)
{
var matchs = regBrackets.Matches(query);
var leftBracketCount = 0;
foreach (Match match in matchs)
{
if (match.Value == "(" || match.Value == "[")
{
leftBracketCount++;
}
else
{
leftBracketCount--;
}
}
return leftBracketCount == 0;
}
protected override void InitInternal(PluginInitContext context)
{
this.context = context;
}
public override string Name
{
get { return "Calculator"; }
}
public override string IcoPath
{
get { return @"Images\calculator.png"; }
}
public override string Description
{
get { return base.Description; }
}
}
}

View File

@@ -0,0 +1,175 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Wox.Infrastructure;
namespace Wox.Plugin.SystemPlugins
{
public class DirectoryIndicator : BaseSystemPlugin
{
private PluginInitContext context;
private static List<string> driverNames = null;
private static Dictionary<string, DirectoryInfo[]> parentDirectories = new Dictionary<string, DirectoryInfo[]>();
protected override List<Result> QueryInternal(Query query)
{
List<Result> results = new List<Result>();
if (string.IsNullOrEmpty(query.RawQuery))
{
// clear the cache
if (parentDirectories.Count > 0)
parentDirectories.Clear();
return results;
}
InitialDriverList();
var input = query.RawQuery.ToLower();
if (driverNames.FirstOrDefault(x => input.StartsWith(x)) == null) return results;
if (Directory.Exists(query.RawQuery))
{
// show all child directory
if (input.EndsWith("\\") || input.EndsWith("/"))
{
var dirInfo = new DirectoryInfo(query.RawQuery);
var dirs = dirInfo.GetDirectories();
var parentDirKey = input.TrimEnd('\\', '/');
if (!parentDirectories.ContainsKey(parentDirKey))
parentDirectories.Add(parentDirKey, dirs);
foreach (var dir in dirs)
{
if ((dir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
continue;
var dirPath = dir.FullName;
Result result = new Result
{
Title = dir.Name,
IcoPath = "Images/folder.png",
Action = (c) =>
{
context.ChangeQuery(dirPath);
return false;
}
};
results.Add(result);
}
if (results.Count == 0)
{
Result result = new Result
{
Title = "Open this directory",
SubTitle = "No files in this directory",
IcoPath = "Images/folder.png",
Action = (c) =>
{
Process.Start(query.RawQuery);
return true;
}
};
results.Add(result);
}
}
else
{
Result result = new Result
{
Title = "Open this directory",
SubTitle = string.Format("path: {0}", query.RawQuery),
Score = 50,
IcoPath = "Images/folder.png",
Action = (c) =>
{
Process.Start(query.RawQuery);
return true;
}
};
results.Add(result);
}
}
// change to search in current directory
var parentDir = Path.GetDirectoryName(input);
if (!string.IsNullOrEmpty(parentDir) && results.Count == 0)
{
parentDir = parentDir.TrimEnd('\\', '/');
if (parentDirectories.ContainsKey(parentDir))
{
var dirs = parentDirectories[parentDir];
var queryFileName = Path.GetFileName(query.RawQuery).ToLower();
var fuzzy = FuzzyMatcher.Create(queryFileName);
foreach (var dir in dirs)
{
if ((dir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
continue;
var matchResult = fuzzy.Evaluate(dir.Name);
if (!matchResult.Success)
continue;
var dirPath = dir.FullName;
Result result = new Result
{
Title = dir.Name,
IcoPath = "Images/folder.png",
Score = matchResult.Score,
Action = (c) =>
{
context.ChangeQuery(dirPath);
return false;
}
};
results.Add(result);
}
}
}
return results;
}
private void InitialDriverList()
{
if (driverNames == null)
{
driverNames = new List<string>();
var allDrives = DriveInfo.GetDrives();
foreach (var driver in allDrives)
{
driverNames.Add(driver.Name.ToLower().TrimEnd('\\'));
}
}
}
protected override void InitInternal(PluginInitContext context)
{
this.context = context;
}
public override string Name
{
get { return "File System"; }
}
public override string IcoPath
{
get { return @"Images\folder.png"; }
}
public override string Description
{
get { return base.Description; }
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace Wox.Plugin.SystemPlugins
{
public interface IProgramSource
{
List<Program> LoadPrograms();
int BonusPoints { get; set; }
}
public abstract class AbstractProgramSource : IProgramSource
{
public abstract List<Program> LoadPrograms();
public int BonusPoints
{
get; set;
}
protected Program CreateEntry(string file)
{
Program p = new Program()
{
Title = global::System.IO.Path.GetFileNameWithoutExtension(file),
IcoPath = file,
ExecutePath = file
};
switch (global::System.IO.Path.GetExtension(file).ToLower())
{
case ".exe":
p.ExecuteName = global::System.IO.Path.GetFileName(file);
try
{
FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(file);
if (versionInfo.FileDescription != null && versionInfo.FileDescription != string.Empty) p.Title = versionInfo.FileDescription;
}
catch (Exception) { }
break;
}
return p;
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Wox.Plugin.SystemPlugins
{
public interface ISystemPlugin : IPlugin
{
string Name { get; }
string Description { get; }
}
}

View File

@@ -0,0 +1,56 @@
<UserControl x:Class="Wox.Plugin.SystemPlugins.ProgramSetting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:infrastructure="clr-namespace:Wox.Infrastructure;assembly=Wox.Infrastructure"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<ListView x:Name="programSourceView" Grid.Row="0">
<ListView.View>
<GridView>
<GridViewColumn Header="Location" Width="400">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Location, ConverterParameter=(null), Converter={infrastructure:StringEmptyConverter}}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Type" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Type}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Bonus Points" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding BonusPoints}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Enabled" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Enabled}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<StackPanel Grid.Row="1" HorizontalAlignment="Right" Orientation="Horizontal">
<Button x:Name="btnDeleteProgramSource" Click="btnDeleteProgramSource_OnClick" Width="100" Margin="10" Content="Delete"/>
<Button x:Name="btnEditProgramSource" Click="btnEditProgramSource_OnClick" Width="100" Margin="10" Content="Edit"/>
<Button x:Name="btnAddProgramSource" Click="btnAddProgramSource_OnClick" Width="100" Margin="10" Content="Add"/>
</StackPanel>
<TextBlock Grid.Row="1" Margin="10" HorizontalAlignment="Left" Text="* Restarting required" VerticalAlignment="Center" />
</Grid>
</UserControl>

View File

@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.SystemPlugins
{
/// <summary>
/// Interaction logic for ProgramSetting.xaml
/// </summary>
public partial class ProgramSetting : UserControl
{
public ProgramSetting()
{
InitializeComponent();
Loaded += Setting_Loaded;
}
private void Setting_Loaded(object sender, RoutedEventArgs e)
{
programSourceView.ItemsSource = UserSettingStorage.Instance.ProgramSources;
}
public void ReloadProgramSourceView()
{
programSourceView.Items.Refresh();
}
private void btnAddProgramSource_OnClick(object sender, RoutedEventArgs e)
{
ProgramSourceSetting programSource = new ProgramSourceSetting(this);
programSource.ShowDialog();
}
private void btnDeleteProgramSource_OnClick(object sender, RoutedEventArgs e)
{
ProgramSource seletedProgramSource = programSourceView.SelectedItem as ProgramSource;
if (seletedProgramSource != null &&
MessageBox.Show("Are your sure to delete " + seletedProgramSource.ToString(), "Delete ProgramSource",
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UserSettingStorage.Instance.ProgramSources.Remove(seletedProgramSource);
programSourceView.Items.Refresh();
}
else
{
MessageBox.Show("Please select a program source");
}
}
private void btnEditProgramSource_OnClick(object sender, RoutedEventArgs e)
{
ProgramSource seletedProgramSource = programSourceView.SelectedItem as ProgramSource;
if (seletedProgramSource != null)
{
ProgramSourceSetting programSource = new ProgramSourceSetting(this);
programSource.UpdateItem(seletedProgramSource);
programSource.ShowDialog();
}
else
{
MessageBox.Show("Please select a program source");
}
}
}
}

View File

@@ -0,0 +1,39 @@
<Window x:Class="Wox.Plugin.SystemPlugins.ProgramSourceSetting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen"
Title="ProgramSourceSetting" Height="350" Width="674.766">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Margin="10" FontSize="14" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Type:</TextBlock>
<ComboBox x:Name="cbType" Margin="10" Grid.Row="0" Width="400" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" ItemsSource="{Binding}" SelectionChanged="cbType_SelectionChanged"></ComboBox>
<TextBlock Margin="10" FontSize="14" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Location:</TextBlock>
<TextBox x:Name="tbLocation" Margin="10" Grid.Row="1" Width="400" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBox>
<TextBlock Margin="10" FontSize="14" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">BonusPoints:</TextBlock>
<TextBox x:Name="tbBonusPoints" Margin="10" Grid.Row="2" Width="400" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBox>
<TextBlock Margin="10" FontSize="14" Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Enable:</TextBlock>
<CheckBox x:Name="cbEnable" IsChecked="True" Margin="10" Grid.Row="3" Grid.Column="1" VerticalAlignment="Center"></CheckBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="5" Grid.Column="1">
<Button x:Name="btnCancel" Click="BtnCancel_OnClick" Margin="10 0 10 0" Width="80" Height="25">Cancel</Button>
<Button x:Name="btnAdd" Margin="10 0 10 0" Width="80" Height="25" Click="btnAdd_OnClick">
<TextBlock x:Name="lblAdd">Add</TextBlock>
</Button>
</StackPanel>
</Grid>
</Window>

View File

@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Wox.Infrastructure;
using Wox.Infrastructure.Storage;
using Wox.Infrastructure.Storage.UserSettings;
using MessageBox = System.Windows.MessageBox;
namespace Wox.Plugin.SystemPlugins
{
public partial class ProgramSourceSetting : Window
{
private ProgramSetting settingWindow;
private bool update;
private ProgramSource updateProgramSource;
public ProgramSourceSetting(ProgramSetting settingWidow)
{
this.settingWindow = settingWidow;
InitializeComponent();
this.cbType.ItemsSource = Wox.Plugin.SystemPlugins.Programs.SourceTypes.Select(o => o.Key).ToList();
}
public void UpdateItem(ProgramSource programSource)
{
updateProgramSource = UserSettingStorage.Instance.ProgramSources.FirstOrDefault(o => o == programSource);
if (updateProgramSource == null)
{
MessageBox.Show("Invalid program source");
Close();
return;
}
update = true;
lblAdd.Text = "Update";
cbEnable.IsChecked = programSource.Enabled;
cbType.SelectedItem = programSource.Type;
cbType.IsEnabled = false;
tbLocation.Text = programSource.Location;
tbBonusPoints.Text = programSource.BonusPoints.ToString();
}
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
{
Close();
}
private void btnAdd_OnClick(object sender, RoutedEventArgs e)
{
string location = tbLocation.Text;
if (this.tbLocation.IsEnabled == true && string.IsNullOrEmpty(location))
{
MessageBox.Show("Please input Type field");
return;
}
string type = cbType.SelectedItem as string;
if (string.IsNullOrEmpty(type))
{
MessageBox.Show("Please input Type field");
return;
}
int bonusPoint = 0;
int.TryParse(this.tbBonusPoints.Text, out bonusPoint);
if (!update)
{
ProgramSource p = new ProgramSource()
{
Location = this.tbLocation.IsEnabled ? location : null,
Enabled = cbEnable.IsChecked ?? false,
Type = type,
BonusPoints = bonusPoint
};
if (UserSettingStorage.Instance.ProgramSources.Exists(o => o.ToString() == p.ToString() && o != p))
{
MessageBox.Show("Program source already exists!");
return;
}
UserSettingStorage.Instance.ProgramSources.Add(p);
MessageBox.Show(string.Format("Add {0} program source successfully!", p.ToString()));
}
else
{
if (UserSettingStorage.Instance.ProgramSources.Exists(o => o.ToString() == updateProgramSource.ToString() && o != updateProgramSource))
{
MessageBox.Show("Program source already exists!");
return;
}
updateProgramSource.Location = this.tbLocation.IsEnabled ? location : null;
updateProgramSource.Type = type;
updateProgramSource.Enabled = cbEnable.IsChecked ?? false;
updateProgramSource.BonusPoints = bonusPoint;
MessageBox.Show(string.Format("Update {0} program source successfully!", updateProgramSource.ToString()));
}
UserSettingStorage.Instance.Save();
settingWindow.ReloadProgramSourceView();
Close();
}
private void cbType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string item = cbType.SelectedItem as String;
Type type;
if (item != null && Wox.Plugin.SystemPlugins.Programs.SourceTypes.TryGetValue(item, out type))
{
var attrs = type.GetCustomAttributes(typeof(BrowsableAttribute), false);
if (attrs.Length > 0 && (attrs[0] as BrowsableAttribute).Browsable == false)
{
this.tbLocation.IsEnabled = false;
return;
}
}
this.tbLocation.IsEnabled = true;
}
}
}

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.SystemPlugins.ProgramSources
{
[global::System.ComponentModel.Browsable(false)]
public class AppPathsProgramSource: AbstractProgramSource
{
public AppPathsProgramSource()
{
this.BonusPoints = -10;
}
public AppPathsProgramSource(ProgramSource source)
: this()
{
this.BonusPoints = source.BonusPoints;
}
public override List<Program> LoadPrograms()
{
var list = new List<Program>();
ReadAppPaths(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths", list);
ReadAppPaths(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\App Paths", list); //TODO: need test more on 64-bit
return list;
}
private void ReadAppPaths(string rootpath, List<Program> list)
{
using (var root = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(rootpath))
{
if (root == null) return;
foreach (var item in root.GetSubKeyNames())
{
using (var key = root.OpenSubKey(item))
{
object path = key.GetValue("");
if (path is string && global::System.IO.File.Exists((string)path))
{
var entry = CreateEntry((string)path);
entry.ExecuteName = item;
list.Add(entry);
}
key.Close();
}
}
}
}
public override string ToString()
{
return typeof(AppPathsProgramSource).Name;
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.SystemPlugins.ProgramSources
{
[global::System.ComponentModel.Browsable(false)]
public class CommonStartMenuProgramSource : FileSystemProgramSource
{
[DllImport("shell32.dll")]
static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder, bool fCreate);
const int CSIDL_COMMON_STARTMENU = 0x16; // \Windows\Start Menu\Programs
const int CSIDL_COMMON_PROGRAMS = 0x17;
private static string getPath()
{
StringBuilder commonStartMenuPath = new StringBuilder(560);
SHGetSpecialFolderPath(IntPtr.Zero, commonStartMenuPath, CSIDL_COMMON_PROGRAMS, false);
return commonStartMenuPath.ToString();
}
public CommonStartMenuProgramSource()
: base(getPath())
{
}
public CommonStartMenuProgramSource(ProgramSource source)
: this()
{
this.BonusPoints = source.BonusPoints;
}
public override string ToString()
{
return typeof(CommonStartMenuProgramSource).Name;
}
}
}

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.SystemPlugins.ProgramSources
{
public class FileSystemProgramSource : AbstractProgramSource
{
public string BaseDirectory;
public List<string> Suffixes = new List<string>() { "lnk", "exe", "appref-ms" };
public FileSystemProgramSource(string baseDirectory)
{
BaseDirectory = baseDirectory;
}
public FileSystemProgramSource(string baseDirectory, List<string> suffixes)
: this(baseDirectory)
{
Suffixes = suffixes;
}
public FileSystemProgramSource(ProgramSource source)
: this(source.Location)
{
this.BonusPoints = source.BonusPoints;
}
public override List<Program> LoadPrograms()
{
List<Program> list = new List<Program>();
GetAppFromDirectory(BaseDirectory, list);
return list;
}
private void GetAppFromDirectory(string path, List<Program> list)
{
foreach (string file in Directory.GetFiles(path))
{
if (Suffixes.Any(o => file.EndsWith("." + o)))
{
Program p = CreateEntry(file);
list.Add(p);
}
}
foreach (var subDirectory in Directory.GetDirectories(path))
{
GetAppFromDirectory(subDirectory, list);
}
}
public override string ToString()
{
return typeof(FileSystemProgramSource).Name + ":" + this.BaseDirectory;
}
}
}

View File

@@ -0,0 +1,133 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using IniParser;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.SystemPlugins.ProgramSources
{
public class PortableAppsProgramSource : AbstractProgramSource
{
public string BaseDirectory;
public PortableAppsProgramSource(string baseDirectory)
{
BaseDirectory = baseDirectory;
}
public PortableAppsProgramSource(ProgramSource source)
: this(source.Location)
{
this.BonusPoints = source.BonusPoints;
}
public override List<Program> LoadPrograms()
{
List<Program> list = new List<Program>();
var ini = new IniParser.Parser.IniDataParser();
ini.Configuration.AllowDuplicateKeys = true;
string menuSettingsPath = Path.Combine(BaseDirectory, @"PortableApps.com\Data\PortableAppsMenu.ini");
IniParser.Model.KeyDataCollection appsRenamed = null, appsRecategorized = null, appsHidden = null;
if (File.Exists(menuSettingsPath))
{
var menuSettings = ini.Parse(File.ReadAllText(menuSettingsPath, Encoding.Default));
appsRenamed = menuSettings["AppsRenamed"];
appsRecategorized = menuSettings["AppsRecategorized"];
appsHidden = menuSettings["AppsHidden"];
}
if (appsRenamed == null) appsRenamed = new IniParser.Model.KeyDataCollection();
if (appsRecategorized == null) appsRecategorized = new IniParser.Model.KeyDataCollection();
if (appsHidden == null) appsHidden = new IniParser.Model.KeyDataCollection();
foreach (var appDir in Directory.GetDirectories(BaseDirectory))
{
var appDirName = Path.GetDirectoryName(appDir);
var appInfoPath = Path.Combine(appDir, @"App\AppInfo\appinfo.ini");
var appInfoValid = false;
if (File.Exists(appInfoPath))
{
var appInfo = ini.Parse(File.ReadAllText(appInfoPath, Encoding.Default));
var appName = appInfo["Details"]["Name"] ?? appDirName;
var control = appInfo["Control"];
int count;
if (Int32.TryParse(control["Icons"], out count))
{
appInfoValid = true;
for (int i = 1; i <= count; i++)
{
string cmdline, name, icon;
cmdline = control[String.Format("Start{0}", i)];
name = control[String.Format("Name{0}", i)];
icon = control[String.Format("ExtractIcon{0}", i)];
if (i == 1)
{
if (cmdline == null) cmdline = control["Start"];
if (cmdline == null) continue;
if (name == null) name = appName;
if (icon == null) icon = control["ExtractIcon"];
if (icon == null && !File.Exists(icon = Path.Combine(appDir, @"App\AppInfo\appicon.ico"))) icon = null;
}
if (cmdline == null) continue;
if (name == null) name = String.Format("{0} #{1}", appName, i);
if (icon == null) icon = Path.Combine(appDir, String.Format(@"App\AppInfo\appicon{0}.ico", i));
cmdline = Path.Combine(appDir, cmdline);
var menuKey = (appDirName + @"\" + cmdline).ToLower();
var renamed = appsRenamed[menuKey];
if (renamed != null)
name = renamed;
var hidden = appsHidden[menuKey] == "true";
if (!hidden)
{
Program p = new Program()
{
Title = name,
IcoPath = icon,
ExecutePath = cmdline
};
list.Add(p);
}
}
}
}
if (!appInfoValid)
{
foreach (var item in Directory.GetFiles(appDir, "*.exe", SearchOption.TopDirectoryOnly))
{
var menuKey = Path.GetFullPath(item).Substring(Path.GetFullPath(BaseDirectory).Length + 1).ToLower();
if (appsHidden[menuKey] != "true")
{
var p = CreateEntry(item);
var renamed = appsRenamed[menuKey];
if (renamed != null)
p.Title = renamed;
list.Add(p);
}
}
}
}
return list;
}
public override string ToString()
{
return typeof(PortableAppsProgramSource).Name + ":" + this.BaseDirectory;
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.SystemPlugins.ProgramSources
{
[global::System.ComponentModel.Browsable(false)]
public class UserStartMenuProgramSource : FileSystemProgramSource
{
public UserStartMenuProgramSource()
: base(Environment.GetFolderPath(Environment.SpecialFolder.Programs))
{
}
public UserStartMenuProgramSource(ProgramSource source)
: this()
{
this.BonusPoints = source.BonusPoints;
}
public override string ToString()
{
return typeof(UserStartMenuProgramSource).Name;
}
}
}

View File

@@ -0,0 +1,174 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using Wox.Infrastructure;
using Wox.Infrastructure.Storage;
using Wox.Infrastructure.Storage.UserSettings;
using Wox.Plugin.SystemPlugins.ProgramSources;
namespace Wox.Plugin.SystemPlugins
{
public class Program
{
private static readonly global::System.Text.RegularExpressions.Regex AbbrRegexp = new global::System.Text.RegularExpressions.Regex("[^A-Z0-9]", global::System.Text.RegularExpressions.RegexOptions.Compiled);
private string m_Title;
public string Title
{
get
{
return m_Title;
}
set
{
m_Title = value;
string pinyin = ChineseToPinYin.ToPinYin(m_Title);
PinyinTitle = pinyin.Replace(" ", "").ToLower();
AbbrTitle = AbbrRegexp.Replace(global::System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(pinyin), "");
if (AbbrTitle.Length < 2) AbbrTitle = null;
}
}
public string PinyinTitle { get; private set; }
public string AbbrTitle { get; private set; }
public string IcoPath { get; set; }
public string ExecutePath { get; set; }
public string ExecuteName { get; set; }
public int Score { get; set; }
public IProgramSource Source { get; set; }
}
public class Programs : BaseSystemPlugin, ISettingProvider
{
List<Program> installedList = new List<Program>();
List<IProgramSource> sources = new List<IProgramSource>();
public static Dictionary<string, Type> SourceTypes = new Dictionary<string, Type>() {
{"FileSystemProgramSource", typeof(FileSystemProgramSource)},
{"PortableAppsProgramSource", typeof(PortableAppsProgramSource)},
{"CommonStartMenuProgramSource", typeof(CommonStartMenuProgramSource)},
{"UserStartMenuProgramSource", typeof(UserStartMenuProgramSource)},
{"AppPathsProgramSource", typeof(AppPathsProgramSource)},
};
private PluginInitContext context;
protected override List<Result> QueryInternal(Query query)
{
if (string.IsNullOrEmpty(query.RawQuery) || query.RawQuery.EndsWith(" ") || query.RawQuery.Length <= 1) return new List<Result>();
var fuzzyMather = FuzzyMatcher.Create(query.RawQuery);
List<Program> returnList = installedList.Where(o => MatchProgram(o, fuzzyMather)).ToList();
returnList.ForEach(ScoreFilter);
//return ordered list instead of return the score, because programs scores will affect other
//plugins, the weight of program should be less than the plugins when they showed at the same time.
returnList = returnList.OrderByDescending(o => o.Score).ToList();
return returnList.Select(c => new Result()
{
Title = c.Title,
SubTitle = c.ExecutePath,
IcoPath = c.IcoPath,
Score = 0,
Action = (e) =>
{
context.HideApp();
context.ShellRun(c.ExecutePath);
return true;
}
}).ToList();
}
private bool MatchProgram(Program program, FuzzyMatcher matcher)
{
if (program.AbbrTitle != null && (program.Score = matcher.Evaluate(program.AbbrTitle).Score) > 0) return true;
if ((program.Score = matcher.Evaluate(program.Title).Score) > 0) return true;
if ((program.Score = matcher.Evaluate(program.PinyinTitle).Score) > 0) return true;
if (program.ExecuteName != null && (program.Score = matcher.Evaluate(program.ExecuteName).Score) > 0) return true;
return false;
}
protected override void InitInternal(PluginInitContext context)
{
this.context = context;
if (UserSettingStorage.Instance.ProgramSources == null)
UserSettingStorage.Instance.ProgramSources = UserSettingStorage.Instance.LoadDefaultProgramSources();
UserSettingStorage.Instance.ProgramSources.ForEach(source =>
{
if (source.Enabled)
{
Type sourceClass;
if (SourceTypes.TryGetValue(source.Type, out sourceClass))
{
sources.Add(sourceClass.GetConstructor(
new Type[] { typeof(ProgramSource) }
).Invoke(new object[] { source }) as IProgramSource);
}
else
{
// TODO: invalid class
}
}
});
foreach (var source in sources)
{
var list = source.LoadPrograms();
list.ForEach(o =>
{
o.Source = source;
});
installedList.AddRange(list);
}
// filter duplicate program
installedList = installedList.GroupBy(x => new { x.ExecutePath, x.ExecuteName })
.Select(g => g.First()).ToList();
}
private void ScoreFilter(Program p)
{
p.Score += p.Source.BonusPoints;
if (p.Title.Contains("启动") || p.Title.ToLower().Contains("start"))
p.Score += 10;
if (p.Title.Contains("帮助") || p.Title.ToLower().Contains("help") || p.Title.Contains("文档") || p.Title.ToLower().Contains("documentation"))
p.Score -= 10;
if (p.Title.Contains("卸载") || p.Title.ToLower().Contains("uninstall"))
p.Score -= 20;
}
public override string Name
{
get { return "Programs"; }
}
public override string IcoPath
{
get { return @"Images\app.png"; }
}
public override string Description
{
get { return base.Description; }
}
#region ISettingProvider Members
public System.Windows.Controls.Control CreateSettingPanel()
{
return new ProgramSetting();
}
#endregion
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Wox.Plugin.SystemPlugins")]
[assembly: AssemblyDescription("https://github.com/qianlifeng/Wox")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.SystemPlugins")]
[assembly: AssemblyCopyright("The MIT License (MIT)")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("bab8d3dc-d6be-42b3-8aa4-24801d667528")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Wox.Infrastructure;
using YAMP.Numerics;
namespace Wox.Plugin.SystemPlugins.SuggestionSources
{
public class Google : AbstractSuggestionSource
{
public override List<string> GetSuggestions(string query)
{
try
{
var response =
HttpRequest.CreateGetHttpResponse(
"https://www.google.com/complete/search?output=chrome&q=" + Uri.EscapeUriString(query), null,
null, null);
var stream = response.GetResponseStream();
if (stream != null)
{
var body = new StreamReader(stream).ReadToEnd();
var json = JsonConvert.DeserializeObject(body) as JContainer;
if (json != null)
{
var results = json[1] as JContainer;
if (results != null)
{
return results.OfType<JValue>().Select(o => o.Value).OfType<string>().ToList();
}
}
}
}
catch
{ }
return null;
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace Wox.Plugin.SystemPlugins.SuggestionSources
{
public interface ISuggestionSource
{
List<string> GetSuggestions(string query);
}
public abstract class AbstractSuggestionSource : ISuggestionSource
{
public abstract List<string> GetSuggestions(string query);
}
}

View File

@@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace Wox.Plugin.SystemPlugins
{
public class Sys : BaseSystemPlugin
{
List<Result> availableResults = new List<Result>();
internal const int EWX_LOGOFF = 0x00000000;
internal const int EWX_SHUTDOWN = 0x00000001;
internal const int EWX_REBOOT = 0x00000002;
internal const int EWX_FORCE = 0x00000004;
internal const int EWX_POWEROFF = 0x00000008;
internal const int EWX_FORCEIFHUNG = 0x00000010;
[DllImport("user32")]
public static extern bool ExitWindowsEx(uint uFlags, uint dwReason);
[DllImport("user32")]
public static extern void LockWorkStation();
protected override List<Result> QueryInternal(Query query)
{
if (string.IsNullOrEmpty(query.RawQuery) || query.RawQuery.EndsWith(" ") || query.RawQuery.Length <= 1) return new List<Result>();
List<Result> results = new List<Result>();
foreach (Result availableResult in availableResults)
{
if (availableResult.Title.ToLower().StartsWith(query.RawQuery.ToLower()))
{
results.Add(availableResult);
}
}
return results;
}
protected override void InitInternal(PluginInitContext context)
{
availableResults.Add(new Result
{
Title = "Shutdown",
SubTitle = "Shutdown Computer",
Score = 100,
IcoPath = "Images\\exit.png",
Action = (c) =>
{
Process.Start("shutdown", "/s /t 0");
return true;
}
});
availableResults.Add(new Result
{
Title = "Log off",
SubTitle = "Log off current user",
Score = 20,
IcoPath = "Images\\logoff.png",
Action = (c) => ExitWindowsEx(EWX_LOGOFF, 0)
});
availableResults.Add(new Result
{
Title = "Lock",
SubTitle = "Lock this computer",
Score = 20,
IcoPath = "Images\\lock.png",
Action = (c) =>
{
LockWorkStation();
return true;
}
});
availableResults.Add(new Result
{
Title = "Exit",
SubTitle = "Close this app",
Score = 110,
IcoPath = "Images\\app.png",
Action = (c) =>
{
context.CloseApp();
return true;
}
});
availableResults.Add(new Result
{
Title = "Setting",
SubTitle = "Tweak this app",
Score = 40,
IcoPath = "Images\\app.png",
Action = (c) =>
{
context.OpenSettingDialog();
return true;
}
});
}
public override string Name
{
get { return "System Commands"; }
}
public override string IcoPath
{
get { return @"Images\lock.png"; }
}
public override string Description
{
get { return base.Description; }
}
}
}

View File

@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wox.Infrastructure;
using Wox.Infrastructure.Storage;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.SystemPlugins
{
public class ThirdpartyPluginIndicator : BaseSystemPlugin
{
private List<PluginPair> allPlugins = new List<PluginPair>();
private Action<string> changeQuery;
protected override List<Result> QueryInternal(Query query)
{
List<Result> results = new List<Result>();
if (string.IsNullOrEmpty(query.RawQuery)) return results;
foreach (PluginMetadata metadata in allPlugins.Select(o => o.Metadata))
{
if (metadata.ActionKeyword.StartsWith(query.RawQuery))
{
PluginMetadata metadataCopy = metadata;
Result result = new Result
{
Title = metadata.ActionKeyword,
SubTitle = string.Format("Activate {0} plugin", metadata.Name),
Score = 50,
IcoPath = "Images/work.png",
Action = (c) =>
{
changeQuery(metadataCopy.ActionKeyword + " ");
return false;
},
};
results.Add(result);
}
}
results.AddRange(UserSettingStorage.Instance.WebSearches.Where(o => o.ActionWord.StartsWith(query.RawQuery) && o.Enabled).Select(n => new Result()
{
Title = n.ActionWord,
SubTitle = string.Format("Activate {0} web search", n.ActionWord),
Score = 50,
IcoPath = "Images/work.png",
Action = (c) =>
{
changeQuery(n.ActionWord + " ");
return false;
}
}));
return results;
}
protected override void InitInternal(PluginInitContext context)
{
allPlugins = context.Plugins;
changeQuery = context.ChangeQuery;
}
public override string Name
{
get { return "Plugins"; }
}
public override string IcoPath
{
get { return @"Images\work.png"; }
}
public override string Description
{
get { return base.Description; }
}
}
}

View File

@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Wox.Infrastructure;
using Wox.Infrastructure.Storage;
using Wox.Infrastructure.Storage.UserSettings;
using Wox.Plugin.SystemPlugins.SuggestionSources;
namespace Wox.Plugin.SystemPlugins
{
public class WebSearchPlugin : BaseSystemPlugin
{
private PluginInitContext context;
protected override List<Result> QueryInternal(Query query)
{
List<Result> results = new List<Result>();
if (string.IsNullOrEmpty(query.ActionName)) return results;
WebSearch webSearch =
UserSettingStorage.Instance.WebSearches.FirstOrDefault(o => o.ActionWord == query.ActionName && o.Enabled);
if (webSearch != null)
{
string keyword = query.ActionParameters.Count > 0 ? query.GetAllRemainingParameter() : "";
string title = keyword;
string subtitle = "Search " + webSearch.Title;
if (string.IsNullOrEmpty(keyword))
{
title = subtitle;
subtitle = null;
}
context.PushResults(query, new List<Result>()
{
new Result()
{
Title = title,
SubTitle = subtitle,
Score = 6,
IcoPath = webSearch.IconPath,
Action = (c) =>
{
Process.Start(webSearch.Url.Replace("{q}", keyword));
return true;
}
}
});
if (!string.IsNullOrEmpty(keyword))
{
ISuggestionSource sugg = new Google();
var result = sugg.GetSuggestions(keyword);
if (result != null)
{
context.PushResults(query, result.Select(o => new Result()
{
Title = o,
SubTitle = subtitle,
Score = 5,
IcoPath = webSearch.IconPath,
Action = (c) =>
{
Process.Start(webSearch.Url.Replace("{q}", o));
return true;
}
}).ToList());
}
}
}
return results;
}
protected override void InitInternal(PluginInitContext context)
{
this.context = context;
if (UserSettingStorage.Instance.WebSearches == null)
UserSettingStorage.Instance.WebSearches = UserSettingStorage.Instance.LoadDefaultWebSearches();
}
public override string Name
{
get { return "Web Searches"; }
}
public override string IcoPath
{
get { return @"Images\app.png"; }
}
public override string Description
{
get { return base.Description; }
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{69CE0206-CB41-453D-88AF-DF86092EF9B8}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.SystemPlugins</RootNamespace>
<AssemblyName>Wox.Plugin.SystemPlugins</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Output\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Output\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="INIFileParser">
<HintPath>..\packages\ini-parser.2.0.2\lib\INIFileParser.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net35\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="WindowsBase" />
<Reference Include="YAMP">
<HintPath>..\packages\YAMP.1.3.0\lib\net35\YAMP.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CMD\CMDStorage.cs" />
<Compile Include="ProgramSetting.xaml.cs">
<DependentUpon>ProgramSetting.xaml</DependentUpon>
</Compile>
<Compile Include="ProgramSourceSetting.xaml.cs">
<DependentUpon>ProgramSourceSetting.xaml</DependentUpon>
</Compile>
<Compile Include="ProgramSources\AppPathsProgramSource.cs" />
<Compile Include="ProgramSources\CommonStartMenuProgramSource.cs" />
<Compile Include="ProgramSources\PortableAppsProgramSource.cs" />
<Compile Include="IProgramSource.cs" />
<Compile Include="BaseSystemPlugin.cs" />
<Compile Include="BrowserBookmarks.cs" />
<Compile Include="Calculator.cs" />
<Compile Include="ProgramSources\FileSystemProgramSource.cs" />
<Compile Include="ProgramSources\UserStartMenuProgramSource.cs" />
<Compile Include="WebSearchPlugin.cs" />
<Compile Include="CMD\CMD.cs" />
<Compile Include="DirectoryIndicator.cs" />
<Compile Include="ISystemPlugin.cs" />
<Compile Include="Programs.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Sys.cs" />
<Compile Include="ThirdpartyPluginIndicator.cs" />
<Compile Include="SuggestionSources\Google.cs" />
<Compile Include="SuggestionSources\ISuggestionSource.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Project>{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Page Include="ProgramSetting.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="ProgramSourceSetting.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ini-parser" version="2.0.2" targetFramework="net35" />
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net35" />
<package id="YAMP" version="1.3.0" targetFramework="net35" />
</packages>