Refactoring. Move system plugins to seperate DLLs.

This commit is contained in:
qianlifeng
2015-01-03 15:20:34 +08:00
parent 203965043e
commit 4243843951
134 changed files with 2209 additions and 1158 deletions

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Wox.Core.Exception
{
public class WoxI18nException:WoxException
{
public WoxI18nException(string msg) : base(msg)
{
}
}
}

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Reflection;
using Wox.Infrastructure.Logger;
using Wox.Plugin;
using Wox.Plugin.SystemPlugins;
//using Wox.Plugin.SystemPlugins;
namespace Wox.Core.Plugin
{
@@ -20,7 +20,7 @@ namespace Wox.Core.Plugin
try
{
Assembly asm = Assembly.Load(AssemblyName.GetAssemblyName(metadata.ExecuteFilePath));
List<Type> types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && (o.BaseType == typeof(BaseSystemPlugin) || o.GetInterfaces().Contains(typeof(IPlugin)))).ToList();
List<Type> types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin))).ToList();
if (types.Count == 0)
{
Log.Warn(string.Format("Couldn't load plugin {0}: didn't find the class that implement IPlugin", metadata.Name));
@@ -35,11 +35,11 @@ namespace Wox.Core.Plugin
Metadata = metadata
};
var sys = pair.Plugin as BaseSystemPlugin;
if (sys != null)
{
sys.PluginDirectory = metadata.PluginDirectory;
}
//var sys = pair.Plugin as BaseSystemPlugin;
//if (sys != null)
//{
// sys.PluginDirectory = metadata.PluginDirectory;
//}
plugins.Add(pair);
}

View File

@@ -25,10 +25,9 @@ namespace Wox.Core.Plugin
public static List<PluginMetadata> Parse(List<string> pluginDirectories)
{
pluginMetadatas.Clear();
ParseSystemPlugins();
foreach (string pluginDirectory in pluginDirectories)
{
ParseUserPlugins(pluginDirectory);
ParsePluginConfigs(pluginDirectory);
}
if (PluginManager.DebuggerMode != null)
@@ -39,31 +38,7 @@ namespace Wox.Core.Plugin
return pluginMetadatas;
}
private static void ParseSystemPlugins()
{
string systemPluginPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"Wox.Plugin.SystemPlugins.dll");
if (!File.Exists(systemPluginPath))
{
throw new WoxCritialException("System Plugin DLL is missing.");
}
pluginMetadatas.Add(new PluginMetadata()
{
Name = "System Plugins",
Author = "System",
Description = "system plugins collection",
Website = "http://www.getwox.com",
Language = AllowedLanguage.CSharp,
Version = "1.0.0",
PluginType = PluginType.System,
ActionKeyword = "*",
ExecuteFileName = "Wox.Plugin.SystemPlugins.dll",
PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
});
}
private static void ParseUserPlugins(string pluginDirectory)
private static void ParsePluginConfigs(string pluginDirectory)
{
if (!Directory.Exists(pluginDirectory)) return;

View File

@@ -3,13 +3,13 @@ using System.Linq;
using System.Threading;
using Wox.Infrastructure.Storage.UserSettings;
using Wox.Plugin;
using Wox.Plugin.SystemPlugins;
//using Wox.Plugin.SystemPlugins;
namespace Wox.Core.Plugin.QueryDispatcher
{
public class SystemPluginQueryDispatcher : IQueryDispatcher
{
private IEnumerable<PluginPair> allSytemPlugins = PluginManager.AllPlugins.Where(o => o.Metadata.PluginType == PluginType.System);
private IEnumerable<PluginPair> allSytemPlugins = PluginManager.AllPlugins.Where(o => o.Metadata.ActionKeyword == "*");
public void Dispatch(Query query)
{

View File

@@ -0,0 +1,5 @@
There are two kinds of plugins:
1. System plugin
Those plugins that action keyword is "*", those plugin doesn't need action keyword
2. User Plugin
Those plugins that contains customized action keyword

13
Wox.Core/Theme/ITheme.cs Normal file
View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Wox.Core.Theme
{
interface ITheme
{
void ChangeTheme(string themeName);
List<string> LoadAvailableThemes();
}
}

129
Wox.Core/Theme/Theme.cs Normal file
View File

@@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Wox.Core.UI;
using Wox.Infrastructure.Logger;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Core.Theme
{
public class Theme : IUIResource,ITheme
{
private static List<string> themeDirectories = new List<string>();
static Theme()
{
themeDirectories.Add(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Themes"));
string userProfilePath = Environment.GetEnvironmentVariable("USERPROFILE");
if (userProfilePath != null)
{
themeDirectories.Add(Path.Combine(Path.Combine(userProfilePath, ".Wox"), "Themes"));
}
MakesureThemeDirectoriesExist();
}
private static void MakesureThemeDirectoriesExist()
{
foreach (string pluginDirectory in themeDirectories)
{
if (!Directory.Exists(pluginDirectory))
{
try
{
Directory.CreateDirectory(pluginDirectory);
}
catch (System.Exception e)
{
Log.Error(e.Message);
}
}
}
}
public void ChangeTheme(string themeName)
{
string themePath = GetThemePath(themeName);
if (string.IsNullOrEmpty(themePath))
{
themePath = GetThemePath("Dark");
if (string.IsNullOrEmpty(themePath))
{
throw new System.Exception("Change theme failed");
}
}
UserSettingStorage.Instance.Theme = themeName;
UserSettingStorage.Instance.Save();
ResourceMerger.ApplyResources();
}
public ResourceDictionary GetResourceDictionary()
{
var dict = new ResourceDictionary
{
Source = new Uri(GetThemePath(UserSettingStorage.Instance.Theme), UriKind.Absolute)
};
Style queryBoxStyle = dict["QueryBoxStyle"] as Style;
if (queryBoxStyle != null)
{
queryBoxStyle.Setters.Add(new Setter(TextBox.FontFamilyProperty, new FontFamily(UserSettingStorage.Instance.QueryBoxFont)));
queryBoxStyle.Setters.Add(new Setter(TextBox.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontStyle)));
queryBoxStyle.Setters.Add(new Setter(TextBox.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontWeight)));
queryBoxStyle.Setters.Add(new Setter(TextBox.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontStretch)));
}
Style resultItemStyle = dict["ItemTitleStyle"] as Style;
Style resultSubItemStyle = dict["ItemSubTitleStyle"] as Style;
Style resultItemSelectedStyle = dict["ItemTitleSelectedStyle"] as Style;
Style resultSubItemSelectedStyle = dict["ItemSubTitleSelectedStyle"] as Style;
if (resultItemStyle != null && resultSubItemStyle != null && resultSubItemSelectedStyle != null && resultItemSelectedStyle != null)
{
Setter fontFamily = new Setter(TextBlock.FontFamilyProperty, new FontFamily(UserSettingStorage.Instance.ResultItemFont));
Setter fontStyle = new Setter(TextBlock.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontStyle));
Setter fontWeight = new Setter(TextBlock.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontWeight));
Setter fontStretch = new Setter(TextBlock.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontStretch));
Setter[] setters = new Setter[] { fontFamily, fontStyle, fontWeight, fontStretch };
Array.ForEach(new Style[] { resultItemStyle, resultSubItemStyle, resultItemSelectedStyle, resultSubItemSelectedStyle }, o => Array.ForEach(setters, p => o.Setters.Add(p)));
}
return dict;
}
public List<string> LoadAvailableThemes()
{
List<string> themes = new List<string>();
foreach (var themeDirectory in themeDirectories)
{
themes.AddRange(
Directory.GetFiles(themeDirectory)
.Where(filePath => filePath.EndsWith(".xaml") && !filePath.EndsWith("Base.xaml"))
.ToList());
}
return themes;
}
private string GetThemePath(string themeName)
{
foreach (string themeDirectory in themeDirectories)
{
string path = Path.Combine(themeDirectory, themeName + ".xaml");
if (File.Exists(path))
{
return path;
}
}
return string.Empty;
}
}
}

View File

@@ -1,26 +1,16 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Wox.Core.UI;
using Wox.Infrastructure.Logger;
using Wox.Infrastructure.Storage.UserSettings;
using System.Text;
namespace Wox.Core.Theme
{
public class ThemeManager : IUIResource
public class ThemeManager
{
private static List<string> themeDirectories = new List<string>();
private static ThemeManager instance;
private static Theme instance;
private static object syncObject = new object();
private ThemeManager() { }
public static ThemeManager Instance
public static Theme Theme
{
get
{
@@ -30,122 +20,12 @@ namespace Wox.Core.Theme
{
if (instance == null)
{
instance = new ThemeManager();
instance = new Theme();
}
}
}
return instance;
}
}
static ThemeManager()
{
themeDirectories.Add(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Themes"));
string userProfilePath = Environment.GetEnvironmentVariable("USERPROFILE");
if (userProfilePath != null)
{
themeDirectories.Add(Path.Combine(Path.Combine(userProfilePath, ".Wox"), "Themes"));
}
MakesureThemeDirectoriesExist();
}
private static void MakesureThemeDirectoriesExist()
{
foreach (string pluginDirectory in themeDirectories)
{
if (!Directory.Exists(pluginDirectory))
{
try
{
Directory.CreateDirectory(pluginDirectory);
}
catch (System.Exception e)
{
Log.Error(e.Message);
}
}
}
}
public void ChangeTheme(string themeName)
{
string themePath = GetThemePath(themeName);
if (string.IsNullOrEmpty(themePath))
{
themePath = GetThemePath("Dark");
if (string.IsNullOrEmpty(themePath))
{
throw new System.Exception("Change theme failed");
}
}
UserSettingStorage.Instance.Theme = themeName;
UserSettingStorage.Instance.Save();
ResourceMerger.ApplyResources();
}
public ResourceDictionary GetResourceDictionary()
{
var dict = new ResourceDictionary
{
Source = new Uri(GetThemePath(UserSettingStorage.Instance.Theme), UriKind.Absolute)
};
Style queryBoxStyle = dict["QueryBoxStyle"] as Style;
if (queryBoxStyle != null)
{
queryBoxStyle.Setters.Add(new Setter(TextBox.FontFamilyProperty, new FontFamily(UserSettingStorage.Instance.QueryBoxFont)));
queryBoxStyle.Setters.Add(new Setter(TextBox.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontStyle)));
queryBoxStyle.Setters.Add(new Setter(TextBox.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontWeight)));
queryBoxStyle.Setters.Add(new Setter(TextBox.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontStretch)));
}
Style resultItemStyle = dict["ItemTitleStyle"] as Style;
Style resultSubItemStyle = dict["ItemSubTitleStyle"] as Style;
Style resultItemSelectedStyle = dict["ItemTitleSelectedStyle"] as Style;
Style resultSubItemSelectedStyle = dict["ItemSubTitleSelectedStyle"] as Style;
if (resultItemStyle != null && resultSubItemStyle != null && resultSubItemSelectedStyle != null && resultItemSelectedStyle != null)
{
Setter fontFamily = new Setter(TextBlock.FontFamilyProperty, new FontFamily(UserSettingStorage.Instance.ResultItemFont));
Setter fontStyle = new Setter(TextBlock.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontStyle));
Setter fontWeight = new Setter(TextBlock.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontWeight));
Setter fontStretch = new Setter(TextBlock.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontStretch));
Setter[] setters = new Setter[] { fontFamily, fontStyle, fontWeight, fontStretch };
Array.ForEach(new Style[] { resultItemStyle, resultSubItemStyle, resultItemSelectedStyle, resultSubItemSelectedStyle }, o => Array.ForEach(setters, p => o.Setters.Add(p)));
}
return dict;
}
public List<string> LoadAvailableThemes()
{
List<string> themes = new List<string>();
foreach (var themeDirectory in themeDirectories)
{
themes.AddRange(
Directory.GetFiles(themeDirectory)
.Where(filePath => filePath.EndsWith(".xaml") && !filePath.EndsWith("Base.xaml"))
.ToList());
}
return themes;
}
private string GetThemePath(string themeName)
{
foreach (string themeDirectory in themeDirectories)
{
string path = Path.Combine(themeDirectory, themeName + ".xaml");
if (File.Exists(path))
{
return path;
}
}
return string.Empty;
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace Wox.Core.UI
{
/// <summary>
/// Object implement this interface will have the ability to has its own UI styles
/// </summary>
interface IUIResource
{
ResourceDictionary GetResourceDictionary();
}
}

View File

@@ -56,8 +56,15 @@
<Compile Include="Exception\WoxCritialException.cs" />
<Compile Include="Exception\WoxException.cs" />
<Compile Include="Exception\WoxHttpException.cs" />
<Compile Include="Exception\WoxI18nException.cs" />
<Compile Include="Exception\WoxJsonRPCException.cs" />
<Compile Include="i18n\AvailableLanguages.cs" />
<Compile Include="i18n\IInternationalization.cs" />
<Compile Include="i18n\Internationalization.cs" />
<Compile Include="i18n\InternationalizationManager.cs" />
<Compile Include="i18n\Language.cs" />
<Compile Include="Theme\ITheme.cs" />
<Compile Include="Theme\ThemeManager.cs" />
<Compile Include="UI\IUIResource.cs" />
<Compile Include="UI\ResourceMerger.cs" />
<Compile Include="Plugin\PluginInstaller.cs" />
@@ -75,9 +82,10 @@
<Compile Include="Plugin\PythonPlugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Theme\FontHelper.cs" />
<Compile Include="Theme\ThemeManager.cs" />
<Compile Include="Theme\Theme.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Plugin\README.md" />
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
@@ -85,10 +93,6 @@
<Project>{4fd29318-a8ab-4d8f-aa47-60bc241b8da3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\Wox.Plugin.SystemPlugins\Wox.Plugin.SystemPlugins.csproj">
<Project>{69ce0206-cb41-453d-88af-df86092ef9b8}</Project>
<Name>Wox.Plugin.SystemPlugins</Name>
</ProjectReference>
<ProjectReference Include="..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Wox.Core.i18n
{
internal static class AvailableLanguages
{
public static Language English = new Language("en", "English");
public static Language Chinese = new Language("zh-cn", "中文");
public static Language Chinese_TW = new Language("zh-tw", "中文(繁体)");
public static List<Language> GetAvailableLanguages()
{
List<Language> languages = new List<Language>
{
English,
Chinese,
Chinese_TW
};
return languages;
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Wox.Core.i18n
{
interface IInternationalization
{
List<Language> LoadAvailableLanguages();
string GetTranslation(string key);
void ChangeLanguage(Language language);
void ChangeLanguage(string languageCode);
}
}

View File

@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using Wox.Core.Exception;
using Wox.Core.UI;
using Wox.Infrastructure.Logger;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Core.i18n
{
public class Internationalization : IInternationalization, IUIResource
{
private static List<string> languageDirectories = new List<string>();
static Internationalization()
{
languageDirectories.Add(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"));
MakesureThemeDirectoriesExist();
}
private static void MakesureThemeDirectoriesExist()
{
foreach (string pluginDirectory in languageDirectories)
{
if (!Directory.Exists(pluginDirectory))
{
try
{
Directory.CreateDirectory(pluginDirectory);
}
catch (System.Exception e)
{
Log.Error(e.Message);
}
}
}
}
public void ChangeLanguage(string languageCode)
{
Language language = GetLanguageByLanguageCode(languageCode);
ChangeLanguage(language);
}
private Language GetLanguageByLanguageCode(string languageCode)
{
Language language = AvailableLanguages.GetAvailableLanguages().FirstOrDefault(o => o.LanguageCode.ToLower() == languageCode.ToLower());
if (language == null)
{
throw new WoxI18nException("Invalid language code:" + languageCode);
}
return language;
}
public void ChangeLanguage(Language language)
{
if(language == null) throw new WoxI18nException("language can't be null");
string path = GetLanguagePath(language);
if (string.IsNullOrEmpty(path))
{
path = GetLanguagePath(AvailableLanguages.English);
if (string.IsNullOrEmpty(path))
{
throw new System.Exception("Change Language failed");
}
}
UserSettingStorage.Instance.Language = language.LanguageCode;
UserSettingStorage.Instance.Save();
ResourceMerger.ApplyResources();
}
public ResourceDictionary GetResourceDictionary()
{
return new ResourceDictionary
{
Source = new Uri(GetLanguagePath(UserSettingStorage.Instance.Language), UriKind.Absolute)
};
}
public List<Language> LoadAvailableLanguages()
{
return AvailableLanguages.GetAvailableLanguages();
}
public string GetTranslation(string key)
{
try
{
object translation = Application.Current.FindResource(key);
if (translation == null)
{
return "NoTranslation";
}
return translation.ToString();
}
catch
{
return "NoTranslation";
}
}
private string GetLanguagePath(string languageCode)
{
Language language = GetLanguageByLanguageCode(languageCode);
return GetLanguagePath(language);
}
private string GetLanguagePath(Language language)
{
foreach (string directory in languageDirectories)
{
string path = Path.Combine(directory, language.LanguageCode + ".xaml");
if (File.Exists(path))
{
return path;
}
}
return string.Empty;
}
}
}

View File

@@ -10,15 +10,12 @@ using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Core.i18n
{
public class InternationalizationManager : IUIResource
public static class InternationalizationManager
{
private static List<string> languageDirectories = new List<string>();
private static InternationalizationManager instance;
private static Internationalization instance;
private static object syncObject = new object();
private InternationalizationManager() { }
public static InternationalizationManager Instance
public static Internationalization Internationalization
{
get
{
@@ -28,114 +25,12 @@ namespace Wox.Core.i18n
{
if (instance == null)
{
instance = new InternationalizationManager();
instance = new Internationalization();
}
}
}
return instance;
}
}
static InternationalizationManager()
{
languageDirectories.Add(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"));
string userProfilePath = Environment.GetEnvironmentVariable("USERPROFILE");
if (userProfilePath != null)
{
languageDirectories.Add(Path.Combine(Path.Combine(userProfilePath, ".Wox"), "Languages"));
}
MakesureThemeDirectoriesExist();
}
private static void MakesureThemeDirectoriesExist()
{
foreach (string pluginDirectory in languageDirectories)
{
if (!Directory.Exists(pluginDirectory))
{
try
{
Directory.CreateDirectory(pluginDirectory);
}
catch (System.Exception e)
{
Log.Error(e.Message);
}
}
}
}
public void ChangeLanguage(string name)
{
string path = GetLanguagePath(name);
if (string.IsNullOrEmpty(path))
{
path = GetLanguagePath("English");
if (string.IsNullOrEmpty(path))
{
throw new System.Exception("Change Language failed");
}
}
UserSettingStorage.Instance.Language = name;
UserSettingStorage.Instance.Save();
ResourceMerger.ApplyResources();
}
public ResourceDictionary GetResourceDictionary()
{
return new ResourceDictionary
{
Source = new Uri(GetLanguagePath(UserSettingStorage.Instance.Language), UriKind.Absolute)
};
}
public List<string> LoadAvailableLanguages()
{
List<string> themes = new List<string>();
foreach (var directory in languageDirectories)
{
themes.AddRange(
Directory.GetFiles(directory)
.Where(filePath => filePath.EndsWith(".xaml"))
.Select(Path.GetFileNameWithoutExtension)
.ToList());
}
return themes;
}
public string GetTranslation(string key)
{
try
{
object translation = Application.Current.FindResource(key);
if (translation == null)
{
return "NoTranslation";
}
return translation.ToString();
}
catch
{
return "NoTranslation";
}
}
private string GetLanguagePath(string name)
{
foreach (string directory in languageDirectories)
{
string path = Path.Combine(directory, name + ".xaml");
if (File.Exists(path))
{
return path;
}
}
return string.Empty;
}
}
}

23
Wox.Core/i18n/Language.cs Normal file
View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Wox.Core.i18n
{
public class Language
{
public Language(string code, string display)
{
LanguageCode = code;
Display = display;
}
/// <summary>
/// E.g. En or Zh-CN
/// </summary>
public string LanguageCode { get; set; }
public string Display { get; set; }
}
}