Remove instance logic for BinaryStorage and JsonStorage, part 1

1. part of #389
2. huge refactoring
This commit is contained in:
bao-qian 2016-04-21 01:53:21 +01:00
parent 0bcb76fa81
commit 8d10c9aa41
52 changed files with 502 additions and 584 deletions

View File

@ -8,6 +8,7 @@ using WindowsInput;
using WindowsInput.Native; using WindowsInput.Native;
using Wox.Infrastructure.Hotkey; using Wox.Infrastructure.Hotkey;
using Wox.Infrastructure.Logger; using Wox.Infrastructure.Logger;
using Wox.Infrastructure.Storage;
using Control = System.Windows.Controls.Control; using Control = System.Windows.Controls.Control;
namespace Wox.Plugin.CMD namespace Wox.Plugin.CMD
@ -17,7 +18,20 @@ namespace Wox.Plugin.CMD
private PluginInitContext context; private PluginInitContext context;
private bool WinRStroked; private bool WinRStroked;
private readonly KeyboardSimulator keyboardSimulator = new KeyboardSimulator(new InputSimulator()); private readonly KeyboardSimulator keyboardSimulator = new KeyboardSimulator(new InputSimulator());
private readonly CMDStorage _settings = CMDStorage.Instance;
private readonly CMDHistory _settings;
private readonly PluginSettingsStorage<CMDHistory> _storage;
public CMD()
{
_storage = new PluginSettingsStorage<CMDHistory>();
_settings = _storage.Load();
}
~CMD()
{
_storage.Save();
}
public List<Result> Query(Query query) public List<Result> Query(Query query)
{ {
@ -81,7 +95,7 @@ namespace Wox.Plugin.CMD
private List<Result> GetHistoryCmds(string cmd, Result result) private List<Result> GetHistoryCmds(string cmd, Result result)
{ {
IEnumerable<Result> history = _settings.CMDHistory.Where(o => o.Key.Contains(cmd)) IEnumerable<Result> history = _settings.Count.Where(o => o.Key.Contains(cmd))
.OrderByDescending(o => o.Value) .OrderByDescending(o => o.Value)
.Select(m => .Select(m =>
{ {
@ -127,7 +141,7 @@ namespace Wox.Plugin.CMD
private List<Result> ResultsFromlHistory() private List<Result> ResultsFromlHistory()
{ {
IEnumerable<Result> history = _settings.CMDHistory.OrderByDescending(o => o.Value) IEnumerable<Result> history = _settings.Count.OrderByDescending(o => o.Value)
.Select(m => new Result .Select(m => new Result
{ {
Title = m.Key, Title = m.Key,

View File

@ -5,9 +5,9 @@ namespace Wox.Plugin.CMD
{ {
public partial class CMDSetting : UserControl public partial class CMDSetting : UserControl
{ {
private readonly CMDStorage _settings; private readonly CMDHistory _settings;
public CMDSetting(CMDStorage settings) public CMDSetting(CMDHistory settings)
{ {
InitializeComponent(); InitializeComponent();
_settings = settings; _settings = settings;
@ -21,24 +21,20 @@ namespace Wox.Plugin.CMD
cbLeaveCmdOpen.Checked += (o, e) => cbLeaveCmdOpen.Checked += (o, e) =>
{ {
_settings.LeaveCmdOpen = true; _settings.LeaveCmdOpen = true;
_settings.Save();
}; };
cbLeaveCmdOpen.Unchecked += (o, e) => cbLeaveCmdOpen.Unchecked += (o, e) =>
{ {
_settings.LeaveCmdOpen = false; _settings.LeaveCmdOpen = false;
_settings.Save();
}; };
cbReplaceWinR.Checked += (o, e) => cbReplaceWinR.Checked += (o, e) =>
{ {
_settings.ReplaceWinR = true; _settings.ReplaceWinR = true;
_settings.Save();
}; };
cbReplaceWinR.Unchecked += (o, e) => cbReplaceWinR.Unchecked += (o, e) =>
{ {
_settings.ReplaceWinR = false; _settings.ReplaceWinR = false;
_settings.Save();
}; };
} }
} }

View File

@ -1,40 +1,26 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using Newtonsoft.Json; using Newtonsoft.Json;
using Wox.Infrastructure.Storage; using Wox.Infrastructure.Storage;
namespace Wox.Plugin.CMD namespace Wox.Plugin.CMD
{ {
public class CMDStorage : JsonStrorage<CMDStorage> public class CMDHistory
{ {
[JsonProperty] public bool ReplaceWinR { get; set; } = true;
public bool ReplaceWinR { get; set; }
[JsonProperty]
public bool LeaveCmdOpen { get; set; } public bool LeaveCmdOpen { get; set; }
public Dictionary<string, int> Count = new Dictionary<string, int>();
[JsonProperty]
public Dictionary<string, int> CMDHistory = new Dictionary<string, int>();
protected override string FileName { get; } = "CMDHistory";
protected override CMDStorage LoadDefault()
{
ReplaceWinR = true;
return this;
}
public void AddCmdHistory(string cmdName) public void AddCmdHistory(string cmdName)
{ {
if (CMDHistory.ContainsKey(cmdName)) if (Count.ContainsKey(cmdName))
{ {
CMDHistory[cmdName] += 1; Count[cmdName] += 1;
} }
else else
{ {
CMDHistory.Add(cmdName, 1); Count.Add(cmdName, 1);
} }
Save();
} }
} }
} }

View File

@ -1,44 +1,22 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using Newtonsoft.Json;
using Wox.Infrastructure.Storage; using Wox.Infrastructure.Storage;
using JsonProperty = Newtonsoft.Json.JsonPropertyAttribute;
namespace Wox.Plugin.Everything namespace Wox.Plugin.Everything
{ {
public class ContextMenuStorage : JsonStrorage<ContextMenuStorage> public class Settings
{ {
[JsonProperty] public List<ContextMenu> ContextMenus = new List<ContextMenu>(); public List<ContextMenu> ContextMenus = new List<ContextMenu>();
[JsonProperty] public int MaxSearchCount { get; set; } = 100;
public int MaxSearchCount { get; set; }
public IPublicAPI API { get; set; }
protected override string FileName { get; } = "EverythingContextMenu";
protected override void OnAfterLoad(ContextMenuStorage obj)
{
}
protected override ContextMenuStorage LoadDefault()
{
MaxSearchCount = 100;
return this;
}
} }
public class ContextMenu public class ContextMenu
{ {
[JsonProperty]
public string Name { get; set; } public string Name { get; set; }
[JsonProperty]
public string Command { get; set; } public string Command { get; set; }
[JsonProperty]
public string Argument { get; set; } public string Argument { get; set; }
[JsonProperty]
public string ImagePath { get; set; } public string ImagePath { get; set; }
} }
} }

View File

@ -7,6 +7,8 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.ServiceProcess; using System.ServiceProcess;
using System.Windows; using System.Windows;
using Wox.Infrastructure.Storage;
using Wox.Infrastructure;
using Wox.Plugin.Everything.Everything; using Wox.Plugin.Everything.Everything;
namespace Wox.Plugin.Everything namespace Wox.Plugin.Everything
@ -16,11 +18,26 @@ namespace Wox.Plugin.Everything
private readonly EverythingAPI _api = new EverythingAPI(); private readonly EverythingAPI _api = new EverythingAPI();
private static readonly List<string> ImageExts = new List<string> { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico" }; private static readonly List<string> ImageExts = new List<string> { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico" };
private static readonly List<string> ExecutableExts = new List<string> { ".exe" }; private static readonly List<string> ExecutableExts = new List<string> { ".exe" };
private const string PortableEverything = "PortableEverything";
private const string EverythingProcessName = "Everything"; private const string EverythingProcessName = "Everything";
private const string PortableEverything = "PortableEverything";
internal static string LibraryPath;
private PluginInitContext _context; private PluginInitContext _context;
private ContextMenuStorage _settings = ContextMenuStorage.Instance;
private readonly Settings _settings;
private readonly PluginSettingsStorage<Settings> _storage;
public Main()
{
_storage = new PluginSettingsStorage<Settings>();
_settings = _storage.Load();
}
~Main()
{
_storage.Save();
}
public List<Result> Query(Query query) public List<Result> Query(Query query)
{ {
@ -31,7 +48,6 @@ namespace Wox.Plugin.Everything
if (_settings.MaxSearchCount <= 0) if (_settings.MaxSearchCount <= 0)
{ {
_settings.MaxSearchCount = 50; _settings.MaxSearchCount = 50;
_settings.Save();
} }
if (keyword == "uninstalleverything") if (keyword == "uninstalleverything")
@ -158,19 +174,22 @@ namespace Wox.Plugin.Everything
public void Init(PluginInitContext context) public void Init(PluginInitContext context)
{ {
_context = context; _context = context;
_settings.API = context.API;
LoadLibrary(Path.Combine(context.CurrentPluginMetadata.PluginDirectory, var pluginDirectory = context.CurrentPluginMetadata.PluginDirectory;
PortableEverything, GetCpuType(), "Everything.dll")); var libraryDirectory = Path.Combine(pluginDirectory, PortableEverything, CpuType());
LibraryPath = Path.Combine(libraryDirectory, "Everything.dll");
LoadLibrary(LibraryPath);
//Helper.AddDLLDirectory(libraryDirectory);
StartEverything(); StartEverything();
} }
private string GetCpuType() private string CpuType()
{ {
return (IntPtr.Size == 4) ? "x86" : "x64"; return Environment.Is64BitOperatingSystem ? "x64" : "x86";
} }
private void StartEverything() private void StartEverything()
{ {
if (!CheckEverythingServiceRunning()) if (!CheckEverythingServiceRunning())
@ -268,9 +287,11 @@ namespace Wox.Plugin.Everything
private string GetEverythingPath() private string GetEverythingPath()
{ {
string directory = Path.Combine(_context.CurrentPluginMetadata.PluginDirectory, string directory = Path.Combine(
PortableEverything, GetCpuType(), _context.CurrentPluginMetadata.PluginDirectory,
"Everything.exe"); PortableEverything, CpuType(),
"Everything.exe"
);
return directory; return directory;
} }

View File

@ -4,7 +4,7 @@ using Newtonsoft.Json;
namespace Wox.Plugin.Folder namespace Wox.Plugin.Folder
{ {
[Serializable] [JsonObject(MemberSerialization.OptIn)]
public class FolderLink public class FolderLink
{ {
[JsonProperty] [JsonProperty]

View File

@ -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.Storage;
namespace Wox.Plugin.Folder namespace Wox.Plugin.Folder
{ {
@ -12,7 +13,20 @@ namespace Wox.Plugin.Folder
{ {
private static List<string> driverNames; private static List<string> driverNames;
private PluginInitContext context; private PluginInitContext context;
private FolderStorage _settings = FolderStorage.Instance;
private readonly Settings _settings;
private readonly PluginSettingsStorage<Settings> _storage;
public FolderPlugin()
{
_storage = new PluginSettingsStorage<Settings>();
_settings = _storage.Load();
}
~FolderPlugin()
{
_storage.Save();
}
public Control CreateSettingPanel() public Control CreateSettingPanel()
{ {
@ -26,7 +40,6 @@ namespace Wox.Plugin.Folder
if (_settings.FolderLinks == null) if (_settings.FolderLinks == null)
{ {
_settings.FolderLinks = new List<FolderLink>(); _settings.FolderLinks = new List<FolderLink>();
_settings.Save();
} }
} }

View File

@ -14,9 +14,9 @@ namespace Wox.Plugin.Folder
public partial class FileSystemSettings public partial class FileSystemSettings
{ {
private IPublicAPI woxAPI; private IPublicAPI woxAPI;
private FolderStorage _settings; private Settings _settings;
public FileSystemSettings(IPublicAPI woxAPI, FolderStorage settings) public FileSystemSettings(IPublicAPI woxAPI, Settings settings)
{ {
this.woxAPI = woxAPI; this.woxAPI = woxAPI;
InitializeComponent(); InitializeComponent();
@ -35,7 +35,6 @@ namespace Wox.Plugin.Folder
{ {
_settings.FolderLinks.Remove(selectedFolder); _settings.FolderLinks.Remove(selectedFolder);
lbxFolders.Items.Refresh(); lbxFolders.Items.Refresh();
_settings.Save();
} }
} }
else else
@ -56,8 +55,6 @@ namespace Wox.Plugin.Folder
{ {
var link = _settings.FolderLinks.First(x => x.Path == selectedFolder.Path); var link = _settings.FolderLinks.First(x => x.Path == selectedFolder.Path);
link.Path = folderBrowserDialog.SelectedPath; link.Path = folderBrowserDialog.SelectedPath;
_settings.Save();
} }
lbxFolders.Items.Refresh(); lbxFolders.Items.Refresh();
@ -85,7 +82,6 @@ namespace Wox.Plugin.Folder
} }
_settings.FolderLinks.Add(newFolder); _settings.FolderLinks.Add(newFolder);
_settings.Save();
} }
lbxFolders.Items.Refresh(); lbxFolders.Items.Refresh();
@ -112,7 +108,6 @@ namespace Wox.Plugin.Folder
}; };
_settings.FolderLinks.Add(newFolder); _settings.FolderLinks.Add(newFolder);
_settings.Save();
} }
lbxFolders.Items.Refresh(); lbxFolders.Items.Refresh();

View File

@ -4,11 +4,10 @@ using Wox.Infrastructure.Storage;
namespace Wox.Plugin.Folder namespace Wox.Plugin.Folder
{ {
public class FolderStorage : JsonStrorage<FolderStorage> public class Settings
{ {
[JsonProperty] [JsonProperty]
public List<FolderLink> FolderLinks { get; set; } public List<FolderLink> FolderLinks { get; set; }
protected override string FileName { get; } = "settings_folder_plugin";
} }
} }

View File

@ -14,8 +14,6 @@ namespace Wox.Plugin.PluginIndicator
var results = from keyword in PluginManager.NonGlobalPlugins.Keys var results = from keyword in PluginManager.NonGlobalPlugins.Keys
where keyword.StartsWith(query.Terms[0]) where keyword.StartsWith(query.Terms[0])
let metadata = PluginManager.NonGlobalPlugins[keyword].Metadata let metadata = PluginManager.NonGlobalPlugins[keyword].Metadata
let customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs[metadata.ID]
where !customizedPluginConfig.Disabled
select new Result select new Result
{ {
Title = keyword, Title = keyword,

View File

@ -10,16 +10,16 @@ namespace Wox.Plugin.Program
public partial class AddProgramSource public partial class AddProgramSource
{ {
private ProgramSource _editing; private ProgramSource _editing;
private ProgramStorage _settings; private Settings _settings;
public AddProgramSource(ProgramStorage settings) public AddProgramSource(Settings settings)
{ {
_settings = settings; _settings = settings;
InitializeComponent(); InitializeComponent();
Suffixes.Text = string.Join(";", settings.ProgramSuffixes); Suffixes.Text = string.Join(";", settings.ProgramSuffixes);
} }
public AddProgramSource(ProgramSource edit, ProgramStorage settings) public AddProgramSource(ProgramSource edit, Settings settings)
{ {
_editing = edit; _editing = edit;
Directory.Text = _editing.Location; Directory.Text = _editing.Location;
@ -65,7 +65,6 @@ namespace Wox.Plugin.Program
_editing.Suffixes = Suffixes.Text.Split(ProgramSource.SuffixSeperator); _editing.Suffixes = Suffixes.Text.Split(ProgramSource.SuffixSeperator);
} }
_settings.Save();
DialogResult = true; DialogResult = true;
Close(); Close();
} }

View File

@ -5,10 +5,8 @@ using Wox.Infrastructure.Storage;
namespace Wox.Plugin.Program namespace Wox.Plugin.Program
{ {
[Serializable] [Serializable]
public class ProgramCacheStorage : BinaryStorage<ProgramCacheStorage> public class ProgramIndexCache
{ {
public List<Program> Programs = new List<Program>(); public List<Program> Programs = new List<Program>();
protected override string FileName { get; } = "ProgramIndexCache";
} }
} }

View File

@ -11,9 +11,9 @@ namespace Wox.Plugin.Program
public partial class ProgramSetting : UserControl public partial class ProgramSetting : UserControl
{ {
private PluginInitContext context; private PluginInitContext context;
private ProgramStorage _settings; private Settings _settings;
public ProgramSetting(PluginInitContext context, ProgramStorage settings) public ProgramSetting(PluginInitContext context, Settings settings)
{ {
this.context = context; this.context = context;
InitializeComponent(); InitializeComponent();
@ -58,7 +58,6 @@ namespace Wox.Plugin.Program
if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes) if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{ {
_settings.ProgramSources.Remove(selectedProgramSource); _settings.ProgramSources.Remove(selectedProgramSource);
_settings.Save();
ReIndexing(); ReIndexing();
} }
} }
@ -127,7 +126,6 @@ namespace Wox.Plugin.Program
Enabled = true Enabled = true
}); });
_settings.Save();
ReIndexing(); ReIndexing();
} }
} }
@ -137,14 +135,12 @@ namespace Wox.Plugin.Program
private void StartMenuEnabled_Click(object sender, RoutedEventArgs e) private void StartMenuEnabled_Click(object sender, RoutedEventArgs e)
{ {
_settings.EnableStartMenuSource = StartMenuEnabled.IsChecked ?? false; _settings.EnableStartMenuSource = StartMenuEnabled.IsChecked ?? false;
_settings.Save();
ReIndexing(); ReIndexing();
} }
private void RegistryEnabled_Click(object sender, RoutedEventArgs e) private void RegistryEnabled_Click(object sender, RoutedEventArgs e)
{ {
_settings.EnableRegistrySource = RegistryEnabled.IsChecked ?? false; _settings.EnableRegistrySource = RegistryEnabled.IsChecked ?? false;
_settings.Save();
ReIndexing(); ReIndexing();
} }
} }

View File

@ -1,45 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using Newtonsoft.Json;
using Wox.Infrastructure.Storage;
namespace Wox.Plugin.Program namespace Wox.Plugin.Program
{ {
[Serializable] public class Settings
public class ProgramStorage : JsonStrorage<ProgramStorage>
{ {
[JsonProperty] public List<ProgramSource> ProgramSources { get; set; } = new List<ProgramSource>();
public List<ProgramSource> ProgramSources { get; set; } public string[] ProgramSuffixes { get; set; } = {"bat", "appref-ms", "exe", "lnk"};
public bool EnableStartMenuSource { get; set; } = true;
[JsonProperty] public bool EnableRegistrySource { get; set; } = true;
public string[] ProgramSuffixes { get; set; }
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue(true)]
public bool EnableStartMenuSource { get; set; }
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue(true)]
public bool EnableRegistrySource { get; set; }
protected override ProgramStorage LoadDefault()
{
ProgramSources = new List<ProgramSource>();
EnableStartMenuSource = true;
EnableRegistrySource = true;
return this;
}
protected override void OnAfterLoad(ProgramStorage storage)
{
if (storage.ProgramSuffixes == null || storage.ProgramSuffixes.Length == 0)
{
storage.ProgramSuffixes = new[] {"bat", "appref-ms", "exe", "lnk"};
}
}
protected override string FileName { get; } = "settings_plugin_program";
} }
} }

View File

@ -9,9 +9,9 @@ namespace Wox.Plugin.Program
public partial class ProgramSuffixes public partial class ProgramSuffixes
{ {
private PluginInitContext context; private PluginInitContext context;
private ProgramStorage _settings; private Settings _settings;
public ProgramSuffixes(PluginInitContext context, ProgramStorage settings) public ProgramSuffixes(PluginInitContext context, Settings settings)
{ {
this.context = context; this.context = context;
InitializeComponent(); InitializeComponent();

View File

@ -5,10 +5,10 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using Wox.Infrastructure; using Wox.Infrastructure;
using Wox.Infrastructure.Logger; using Wox.Infrastructure.Logger;
using Wox.Infrastructure.Storage;
using Wox.Plugin.Program.ProgramSources; using Wox.Plugin.Program.ProgramSources;
using Stopwatch = Wox.Infrastructure.Stopwatch; using Stopwatch = Wox.Infrastructure.Stopwatch;
@ -27,8 +27,25 @@ namespace Wox.Plugin.Program
{"AppPathsProgramSource", typeof(AppPathsProgramSource)} {"AppPathsProgramSource", typeof(AppPathsProgramSource)}
}; };
private PluginInitContext _context; private PluginInitContext _context;
private static ProgramCacheStorage _cache = ProgramCacheStorage.Instance;
private static ProgramStorage _settings = ProgramStorage.Instance; private static ProgramIndexCache _cache;
private static BinaryStorage<ProgramIndexCache> _cacheStorage;
private static Settings _settings ;
private readonly PluginSettingsStorage<Settings> _settingsStorage;
public Programs()
{
_settingsStorage = new PluginSettingsStorage<Settings>();
_settings = _settingsStorage.Load();
_cacheStorage = new BinaryStorage<ProgramIndexCache>();
_cache = _cacheStorage.Load();
}
~Programs()
{
_settingsStorage.Save();
_cacheStorage.Save();
}
public List<Result> Query(Query query) public List<Result> Query(Query query)
{ {
@ -62,15 +79,13 @@ namespace Wox.Plugin.Program
public void Init(PluginInitContext context) public void Init(PluginInitContext context)
{ {
this._context = context; _context = context;
Stopwatch.Debug("Preload programs", () => Stopwatch.Debug("Preload programs", () =>
{ {
programs = _cache.Programs; programs = _cache.Programs;
}); });
Log.Info($"Preload {programs.Count} programs from cache"); Log.Info($"Preload {programs.Count} programs from cache");
// happlebao todo fix this Stopwatch.Debug("Program Index", IndexPrograms);
//Stopwatch.Debug("Program Index", IndexPrograms);
IndexPrograms();
} }
public static void IndexPrograms() public static void IndexPrograms()
@ -120,7 +135,6 @@ namespace Wox.Plugin.Program
.Select(g => g.First()).ToList(); .Select(g => g.First()).ToList();
_cache.Programs = programs; _cache.Programs = programs;
_cache.Save();
} }
} }

View File

@ -2,7 +2,6 @@
namespace Wox.Plugin.WebSearch namespace Wox.Plugin.WebSearch
{ {
[Serializable]
public class WebSearch public class WebSearch
{ {
public string Title { get; set; } public string Title { get; set; }

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows.Controls; using System.Windows.Controls;
using Wox.Infrastructure.Storage;
using Wox.Plugin.WebSearch.Annotations; using Wox.Plugin.WebSearch.Annotations;
using Wox.Plugin.WebSearch.SuggestionSources; using Wox.Plugin.WebSearch.SuggestionSources;
@ -10,9 +11,22 @@ namespace Wox.Plugin.WebSearch
{ {
public class WebSearchPlugin : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IMultipleActionKeywords public class WebSearchPlugin : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IMultipleActionKeywords
{ {
private WebSearchStorage _settings = WebSearchStorage.Instance;
public PluginInitContext Context { get; private set; } public PluginInitContext Context { get; private set; }
private readonly PluginSettingsStorage<Settings> _storage;
private readonly Settings _settings;
public WebSearchPlugin()
{
_storage = new PluginSettingsStorage<Settings>();
_settings = _storage.Load();
}
~WebSearchPlugin()
{
_storage.Save();
}
public List<Result> Query(Query query) public List<Result> Query(Query query)
{ {
List<Result> results = new List<Result>(); List<Result> results = new List<Result>();

View File

@ -18,9 +18,9 @@ namespace Wox.Plugin.WebSearch
private WebSearch _updateWebSearch; private WebSearch _updateWebSearch;
private readonly PluginInitContext _context; private readonly PluginInitContext _context;
private readonly WebSearchPlugin _plugin; private readonly WebSearchPlugin _plugin;
private WebSearchStorage _settings; private Settings _settings;
public WebSearchSetting(WebSearchesSetting settingWidow, WebSearchStorage settings) public WebSearchSetting(WebSearchesSetting settingWidow, Settings settings)
{ {
_plugin = settingWidow.Plugin; _plugin = settingWidow.Plugin;
_context = settingWidow.Context; _context = settingWidow.Context;
@ -122,7 +122,6 @@ namespace Wox.Plugin.WebSearch
}); });
} }
_settings.Save();
_settingWindow.ReloadWebSearchView(); _settingWindow.ReloadWebSearchView();
Close(); Close();
} }

View File

@ -4,22 +4,9 @@ using Wox.Infrastructure.Storage;
namespace Wox.Plugin.WebSearch namespace Wox.Plugin.WebSearch
{ {
public class WebSearchStorage : JsonStrorage<WebSearchStorage> public class Settings
{ {
[JsonProperty] public List<WebSearch> WebSearches { get; set; } = new List<WebSearch>
public List<WebSearch> WebSearches { get; set; }
[JsonProperty]
public bool EnableWebSearchSuggestion { get; set; }
[JsonProperty]
public string WebSearchSuggestionSource { get; set; }
protected override string FileName { get; } = "settings_plugin_websearch";
protected override WebSearchStorage LoadDefault()
{
WebSearches = new List<WebSearch>(new List<WebSearch>()
{ {
new WebSearch new WebSearch
{ {
@ -173,9 +160,10 @@ namespace Wox.Plugin.WebSearch
Url = "http://www.search.yahoo.com/search?p={q}", Url = "http://www.search.yahoo.com/search?p={q}",
Enabled = true Enabled = true
} }
}); };
return this; public bool EnableWebSearchSuggestion { get; set; }
}
public string WebSearchSuggestionSource { get; set; }
} }
} }

View File

@ -10,11 +10,11 @@ namespace Wox.Plugin.WebSearch
/// </summary> /// </summary>
public partial class WebSearchesSetting : UserControl public partial class WebSearchesSetting : UserControl
{ {
private WebSearchStorage _settings; private Settings _settings;
public PluginInitContext Context { get; } public PluginInitContext Context { get; }
public WebSearchPlugin Plugin { get; } public WebSearchPlugin Plugin { get; }
public WebSearchesSetting(WebSearchPlugin plugin, WebSearchStorage settings) public WebSearchesSetting(WebSearchPlugin plugin, Settings settings)
{ {
Context = plugin.Context; Context = plugin.Context;
Plugin = plugin; Plugin = plugin;
@ -97,14 +97,12 @@ namespace Wox.Plugin.WebSearch
{ {
comboBoxSuggestionSource.Visibility = Visibility.Visible; comboBoxSuggestionSource.Visibility = Visibility.Visible;
_settings.EnableWebSearchSuggestion = true; _settings.EnableWebSearchSuggestion = true;
_settings.Save();
} }
private void CbEnableWebSearchSuggestion_OnUnchecked(object sender, RoutedEventArgs e) private void CbEnableWebSearchSuggestion_OnUnchecked(object sender, RoutedEventArgs e)
{ {
comboBoxSuggestionSource.Visibility = Visibility.Collapsed; comboBoxSuggestionSource.Visibility = Visibility.Collapsed;
_settings.EnableWebSearchSuggestion = false; _settings.EnableWebSearchSuggestion = false;
_settings.Save();
} }
private void ComboBoxSuggestionSource_OnSelectionChanged(object sender, SelectionChangedEventArgs e) private void ComboBoxSuggestionSource_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
@ -112,7 +110,6 @@ namespace Wox.Plugin.WebSearch
if (e.AddedItems.Count > 0) if (e.AddedItems.Count > 0)
{ {
_settings.WebSearchSuggestionSource = ((ComboBoxItem)e.AddedItems[0]).Content.ToString(); _settings.WebSearchSuggestionSource = ((ComboBoxItem)e.AddedItems[0]).Content.ToString();
_settings.Save();
} }
} }
} }

View File

@ -25,7 +25,7 @@ namespace Wox.Core.Plugin
/// </summary> /// </summary>
private static readonly List<string> PluginDirectories = new List<string>(); private static readonly List<string> PluginDirectories = new List<string>();
public static IEnumerable<PluginPair> AllPlugins { get; private set; } public static List<PluginPair> AllPlugins { get; private set; }
public static readonly List<PluginPair> GlobalPlugins = new List<PluginPair>(); public static readonly List<PluginPair> GlobalPlugins = new List<PluginPair>();
@ -69,10 +69,8 @@ namespace Wox.Core.Plugin
SetupPluginDirectories(); SetupPluginDirectories();
var metadatas = PluginConfig.Parse(PluginDirectories); var metadatas = PluginConfig.Parse(PluginDirectories);
AllPlugins = (new CSharpPluginLoader().LoadPlugin(metadatas)). AllPlugins = new CSharpPluginLoader().LoadPlugin(metadatas).Concat(
Concat(new JsonRPCPluginLoader<PythonPlugin>().LoadPlugin(metadatas)); new JsonRPCPluginLoader<PythonPlugin>().LoadPlugin(metadatas)).ToList();
} }
public static void InitializePlugins(IPublicAPI api) public static void InitializePlugins(IPublicAPI api)
@ -164,6 +162,42 @@ namespace Wox.Core.Plugin
return GlobalPlugins; return GlobalPlugins;
} }
} }
//happlebao todo prevent plugin initial when plugin is disabled
public static void DisablePlugin(PluginPair plugin)
{
var actionKeywords = plugin.Metadata.ActionKeywords;
if (actionKeywords == null || actionKeywords.Count == 0 || actionKeywords[0] == Query.GlobalPluginWildcardSign)
{
GlobalPlugins.Remove(plugin);
}
else
{
foreach (var actionkeyword in plugin.Metadata.ActionKeywords)
{
NonGlobalPlugins.Remove(actionkeyword);
}
}
AllPlugins.Remove(plugin);
}
public static void EnablePlugin(PluginPair plugin)
{
var actionKeywords = plugin.Metadata.ActionKeywords;
if (actionKeywords == null || actionKeywords.Count == 0 || actionKeywords[0] == Query.GlobalPluginWildcardSign)
{
GlobalPlugins.Add(plugin);
}
else
{
foreach (var actionkeyword in plugin.Metadata.ActionKeywords)
{
NonGlobalPlugins[actionkeyword] = plugin;
}
}
AllPlugins.Add(plugin);
}
public static List<Result> QueryForPlugin(PluginPair pair, Query query) public static List<Result> QueryForPlugin(PluginPair pair, Query query)
{ {
var results = new List<Result>(); var results = new List<Result>();
@ -184,7 +218,7 @@ namespace Wox.Core.Plugin
} }
catch (Exception e) catch (Exception e)
{ {
throw new WoxPluginException(pair.Metadata.Name, $"QueryForPlugin failed", e); throw new WoxPluginException(pair.Metadata.Name, "QueryForPlugin failed", e);
} }
return results; return results;
} }

View File

@ -12,7 +12,7 @@ namespace Wox.Core.Resource
{ {
public class Internationalization : Resource public class Internationalization : Resource
{ {
public UserSettingStorage Settings { get; set; } public UserSettings.Settings Settings { get; set; }
public Internationalization() public Internationalization()
{ {
@ -67,7 +67,6 @@ namespace Wox.Core.Resource
} }
Settings.Language = language.LanguageCode; Settings.Language = language.LanguageCode;
Settings.Save();
ResourceMerger.UpdateResource(this); ResourceMerger.UpdateResource(this);
} }

View File

@ -15,7 +15,7 @@ namespace Wox.Core.Resource
public class Theme : Resource public class Theme : Resource
{ {
private static List<string> themeDirectories = new List<string>(); private static List<string> themeDirectories = new List<string>();
public UserSettingStorage Settings { get; set; } public UserSettings.Settings Settings { get; set; }
public Theme() public Theme()
{ {
@ -55,7 +55,6 @@ namespace Wox.Core.Resource
} }
Settings.Theme = themeName; Settings.Theme = themeName;
Settings.Save();
ResourceMerger.UpdateResource(this); ResourceMerger.UpdateResource(this);
// Exception of FindResource can't be cathed if global exception handle is set // Exception of FindResource can't be cathed if global exception handle is set

View File

@ -22,7 +22,7 @@ namespace Wox.Core.Updater
private const string UpdateFeedURL = "http://upgrade.getwox.com/update.xml"; private const string UpdateFeedURL = "http://upgrade.getwox.com/update.xml";
//private const string UpdateFeedURL = "http://127.0.0.1:8888/update.xml"; //private const string UpdateFeedURL = "http://127.0.0.1:8888/update.xml";
private static SemanticVersion currentVersion; private static SemanticVersion currentVersion;
private UserSettingStorage _settings; public UserSettings.Settings Settings { get; set; }
public event EventHandler PrepareUpdateReady; public event EventHandler PrepareUpdateReady;
public event EventHandler UpdateError; public event EventHandler UpdateError;
@ -44,7 +44,6 @@ namespace Wox.Core.Updater
private UpdaterManager() private UpdaterManager()
{ {
UpdateManager.Instance.UpdateSource = GetUpdateSource(); UpdateManager.Instance.UpdateSource = GetUpdateSource();
_settings = UserSettingStorage.Instance;
} }
public SemanticVersion CurrentVersion public SemanticVersion CurrentVersion
@ -89,7 +88,7 @@ namespace Wox.Core.Updater
try try
{ {
NewRelease = JsonConvert.DeserializeObject<Release>(json); NewRelease = JsonConvert.DeserializeObject<Release>(json);
if (IsNewerThanCurrent(NewRelease) && !_settings.DontPromptUpdateMsg) if (IsNewerThanCurrent(NewRelease) && !Settings.DontPromptUpdateMsg)
{ {
StartUpdate(); StartUpdate();
} }
@ -148,7 +147,7 @@ namespace Wox.Core.Updater
// get out of the way so the console window isn't obstructed // get out of the way so the console window isn't obstructed
try try
{ {
UpdateManager.Instance.ApplyUpdates(true, _settings.EnableUpdateLog, false); UpdateManager.Instance.ApplyUpdates(true, Settings.EnableUpdateLog, false);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -3,7 +3,7 @@
namespace Wox.Core.UserSettings namespace Wox.Core.UserSettings
{ {
public class CustomizedPluginConfig public class PluginSetting
{ {
public string ID { get; set; } public string ID { get; set; }

View File

@ -5,7 +5,7 @@ namespace Wox.Core.UserSettings
public class HttpProxy : IHttpProxy public class HttpProxy : IHttpProxy
{ {
private static readonly HttpProxy instance = new HttpProxy(); private static readonly HttpProxy instance = new HttpProxy();
public UserSettingStorage Settings { get; set; } public Settings Settings { get; set; }
public static HttpProxy Instance => instance; public static HttpProxy Instance => instance;
public bool Enabled => Settings.ProxyEnabled; public bool Enabled => Settings.ProxyEnabled;

View File

@ -2,7 +2,6 @@
namespace Wox.Core.UserSettings namespace Wox.Core.UserSettings
{ {
[Serializable]
public class CustomPluginHotkey public class CustomPluginHotkey
{ {
public string Hotkey { get; set; } public string Hotkey { get; set; }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using Wox.Core.Plugin; using Wox.Core.Plugin;
@ -9,119 +10,66 @@ using Newtonsoft.Json;
namespace Wox.Core.UserSettings namespace Wox.Core.UserSettings
{ {
public class UserSettingStorage : JsonStrorage<UserSettingStorage> public class Settings
{ {
public bool DontPromptUpdateMsg { get; set; } public string Hotkey { get; set; } = "Alt + Space";
public string Language { get; set; } = "en";
public int ActivateTimes { get; set; } public string Theme { get; set; } = "Dark";
public string QueryBoxFont { get; set; } = FontFamily.GenericSansSerif.Name;
public bool EnableUpdateLog { get; set; }
public string Hotkey { get; set; }
public string Language { get; set; }
public string Theme { get; set; }
public string QueryBoxFont { get; set; }
public string QueryBoxFontStyle { get; set; } public string QueryBoxFontStyle { get; set; }
public string QueryBoxFontWeight { get; set; } public string QueryBoxFontWeight { get; set; }
public string QueryBoxFontStretch { get; set; } public string QueryBoxFontStretch { get; set; }
public string ResultFont { get; set; } = FontFamily.GenericSansSerif.Name;
public string ResultFont { get; set; }
public string ResultFontStyle { get; set; } public string ResultFontStyle { get; set; }
public string ResultFontWeight { get; set; } public string ResultFontWeight { get; set; }
public string ResultFontStretch { get; set; } public string ResultFontStretch { get; set; }
public double WindowLeft { get; set; } public double WindowLeft { get; set; }
public double WindowTop { get; set; } public double WindowTop { get; set; }
public int MaxResultsToShow { get; set; } = 6;
public int ActivateTimes { get; set; }
// Order defaults to 0 or -1, so 1 will let this property appear last // Order defaults to 0 or -1, so 1 will let this property appear last
[JsonProperty(Order = 1)] [JsonProperty(Order = 1)]
public Dictionary<string, CustomizedPluginConfig> CustomizedPluginConfigs { get; set; } public Dictionary<string, PluginSetting> PluginSettings { get; set; } = new Dictionary<string, PluginSetting>();
public List<CustomPluginHotkey> CustomPluginHotkeys { get; set; } = new List<CustomPluginHotkey>();
public List<CustomPluginHotkey> CustomPluginHotkeys { get; set; } [Obsolete]
public double Opacity { get; set; } = 1;
[Obsolete]
public OpacityMode OpacityMode { get; set; } = OpacityMode.Normal;
public bool DontPromptUpdateMsg { get; set; }
public bool EnableUpdateLog { get; set; }
public bool StartWoxOnSystemStartup { get; set; } public bool StartWoxOnSystemStartup { get; set; }
[Obsolete]
public double Opacity { get; set; }
[Obsolete]
public OpacityMode OpacityMode { get; set; }
public bool LeaveCmdOpen { get; set; } public bool LeaveCmdOpen { get; set; }
public bool HideWhenDeactive { get; set; } public bool HideWhenDeactive { get; set; }
public bool RememberLastLaunchLocation { get; set; } public bool RememberLastLaunchLocation { get; set; }
public bool IgnoreHotkeysOnFullscreen { get; set; } public bool IgnoreHotkeysOnFullscreen { get; set; }
public string ProxyServer { get; set; } public string ProxyServer { get; set; }
public bool ProxyEnabled { get; set; } public bool ProxyEnabled { get; set; }
public int ProxyPort { get; set; } public int ProxyPort { get; set; }
public string ProxyUserName { get; set; } public string ProxyUserName { get; set; }
public string ProxyPassword { get; set; } public string ProxyPassword { get; set; }
public int MaxResultsToShow { get; set; } public void UpdatePluginSettings()
protected override string FileName { get; } = "Settings";
public void IncreaseActivateTimes()
{
ActivateTimes++;
if (ActivateTimes % 15 == 0)
{
Save();
}
}
protected override UserSettingStorage LoadDefault()
{
DontPromptUpdateMsg = false;
Theme = "Dark";
Language = "en";
CustomizedPluginConfigs = new Dictionary<string, CustomizedPluginConfig>();
Hotkey = "Alt + Space";
QueryBoxFont = FontFamily.GenericSansSerif.Name;
ResultFont = FontFamily.GenericSansSerif.Name;
Opacity = 1;
OpacityMode = OpacityMode.Normal;
LeaveCmdOpen = false;
HideWhenDeactive = false;
CustomPluginHotkeys = new List<CustomPluginHotkey>();
RememberLastLaunchLocation = false;
MaxResultsToShow = 6;
return this;
}
protected override void OnAfterLoad(UserSettingStorage storage)
{ {
var metadatas = PluginManager.AllPlugins.Select(p => p.Metadata); var metadatas = PluginManager.AllPlugins.Select(p => p.Metadata);
if (storage.CustomizedPluginConfigs == null) if (PluginSettings == null)
{ {
var configs = new Dictionary<string, CustomizedPluginConfig>(); var configs = new Dictionary<string, PluginSetting>();
foreach (var metadata in metadatas) foreach (var metadata in metadatas)
{ {
addPluginMetadata(configs, metadata); addPluginMetadata(configs, metadata);
} }
storage.CustomizedPluginConfigs = configs; PluginSettings = configs;
} }
else else
{ {
var configs = storage.CustomizedPluginConfigs; var configs = PluginSettings;
foreach (var metadata in metadatas) foreach (var metadata in metadatas)
{ {
if (configs.ContainsKey(metadata.ID)) if (configs.ContainsKey(metadata.ID))
@ -139,26 +87,12 @@ namespace Wox.Core.UserSettings
} }
} }
} }
if (storage.QueryBoxFont == null)
{
storage.QueryBoxFont = FontFamily.GenericSansSerif.Name;
}
if (storage.ResultFont == null)
{
storage.ResultFont = FontFamily.GenericSansSerif.Name;
}
if (storage.Language == null)
{
storage.Language = "en";
}
} }
private void addPluginMetadata(Dictionary<string, CustomizedPluginConfig> configs, PluginMetadata metadata) private void addPluginMetadata(Dictionary<string, PluginSetting> configs, PluginMetadata metadata)
{ {
configs[metadata.ID] = new CustomizedPluginConfig configs[metadata.ID] = new PluginSetting
{ {
ID = metadata.ID, ID = metadata.ID,
Name = metadata.Name, Name = metadata.Name,
@ -169,10 +103,10 @@ namespace Wox.Core.UserSettings
public void UpdateActionKeyword(PluginMetadata metadata) public void UpdateActionKeyword(PluginMetadata metadata)
{ {
var config = CustomizedPluginConfigs[metadata.ID]; var config = PluginSettings[metadata.ID];
config.ActionKeywords = metadata.ActionKeywords; config.ActionKeywords = metadata.ActionKeywords;
Save();
} }
} }
public enum OpacityMode public enum OpacityMode

View File

@ -1,82 +0,0 @@
using System;
using System.IO;
namespace Wox.Infrastructure.Storage
{
[Serializable]
public abstract class BaseStorage<T> : IStorage where T : class, IStorage, new()
{
protected string DirectoryPath { get; } = Path.Combine(WoxDirectroy.Executable, "Config");
protected string FilePath => Path.Combine(DirectoryPath, FileName + FileSuffix);
protected abstract string FileSuffix { get; }
protected abstract string FileName { get; }
private static object locker = new object();
protected static T serializedObject;
public event Action<T> AfterLoad;
protected virtual void OnAfterLoad(T obj)
{
Action<T> handler = AfterLoad;
if (handler != null) handler(obj);
}
public static T Instance
{
get
{
if (serializedObject == null)
{
lock (locker)
{
if (serializedObject == null)
{
serializedObject = new T();
serializedObject.Load();
}
}
}
return serializedObject;
}
}
/// <summary>
/// if loading storage failed, we will try to load default
/// </summary>
/// <returns></returns>
protected virtual T LoadDefault()
{
return new T();
}
protected abstract void LoadInternal();
protected abstract void SaveInternal();
public void Load()
{
if (!File.Exists(FilePath))
{
if (!Directory.Exists(DirectoryPath))
{
Directory.CreateDirectory(DirectoryPath);
}
File.Create(FilePath).Close();
}
LoadInternal();
OnAfterLoad(serializedObject);
}
public void Save()
{
lock (locker)
{
SaveInternal();
}
}
}
}

View File

@ -1,9 +1,9 @@
using System; using System;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters; using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using Wox.Infrastructure.Logger; using Wox.Infrastructure.Logger;
namespace Wox.Infrastructure.Storage namespace Wox.Infrastructure.Storage
@ -13,55 +13,73 @@ namespace Wox.Infrastructure.Storage
/// Normally, it has better performance, but not readable /// Normally, it has better performance, but not readable
/// You MUST mark implement class as Serializable /// You MUST mark implement class as Serializable
/// </summary> /// </summary>
[Serializable] public class BinaryStorage<T> where T : class, new()
public abstract class BinaryStorage<T> : BaseStorage<T> where T : class, IStorage, new()
{ {
private static object syncObject = new object(); private T _binary;
protected override string FileSuffix
private string FilePath { get; }
private string FileName { get; }
private const string FileSuffix = ".dat";
private string DirectoryPath { get; }
private const string DirectoryName = "Config";
public BinaryStorage()
{ {
get { return ".dat"; } FileName = typeof(T).Name;
DirectoryPath = Path.Combine(WoxDirectroy.Executable, DirectoryName);
FilePath = Path.Combine(DirectoryPath, FileName + FileSuffix); ;
} }
protected override void LoadInternal() public T Load()
{ {
//http://stackoverflow.com/questions/2120055/binaryformatter-deserialize-gives-serializationexception if (!Directory.Exists(DirectoryPath))
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
try
{ {
using (FileStream fileStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) Directory.CreateDirectory(DirectoryPath);
}
if (File.Exists(FilePath))
{
using (var stream = new FileStream(FilePath, FileMode.Open))
{ {
if (fileStream.Length > 0) if (stream.Length > 0)
{ {
BinaryFormatter binaryFormatter = new BinaryFormatter Deserialize(stream);
{
AssemblyFormat = FormatterAssemblyStyle.Simple
};
serializedObject = binaryFormatter.Deserialize(fileStream) as T;
if (serializedObject == null)
{
serializedObject = LoadDefault();
#if (DEBUG)
{
throw new System.Exception("deserialize failed");
}
#endif
}
} }
else else
{ {
serializedObject = LoadDefault(); LoadDefault();
} }
} }
} }
catch (System.Exception e) else
{
LoadDefault();
}
return _binary;
}
private void Deserialize(FileStream stream)
{
//http://stackoverflow.com/questions/2120055/binaryformatter-deserialize-gives-serializationexception
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
BinaryFormatter binaryFormatter = new BinaryFormatter
{
AssemblyFormat = FormatterAssemblyStyle.Simple
};
try
{
_binary = (T)binaryFormatter.Deserialize(stream);
}
catch (SerializationException e)
{ {
Log.Error(e); Log.Error(e);
serializedObject = LoadDefault(); LoadDefault();
#if (DEBUG) }
{ catch (InvalidCastException e)
throw; {
} Log.Error(e);
#endif LoadDefault();
} }
finally finally
{ {
@ -69,6 +87,11 @@ namespace Wox.Infrastructure.Storage
} }
} }
private void LoadDefault()
{
_binary = new T();
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{ {
Assembly ayResult = null; Assembly ayResult = null;
@ -85,33 +108,24 @@ namespace Wox.Infrastructure.Storage
return ayResult; return ayResult;
} }
protected override void SaveInternal() public void Save()
{ {
ThreadPool.QueueUserWorkItem(o => using (var stream = new FileStream(FilePath, FileMode.Create))
{ {
lock (syncObject) BinaryFormatter binaryFormatter = new BinaryFormatter
{ {
try AssemblyFormat = FormatterAssemblyStyle.Simple
{ };
FileStream fileStream = new FileStream(FilePath, FileMode.Create);
BinaryFormatter binaryFormatter = new BinaryFormatter try
{ {
AssemblyFormat = FormatterAssemblyStyle.Simple binaryFormatter.Serialize(stream, _binary);
};
binaryFormatter.Serialize(fileStream, serializedObject);
fileStream.Close();
}
catch (System.Exception e)
{
Log.Error(e);
#if (DEBUG)
{
throw;
}
#endif
}
} }
}); catch (SerializationException e)
{
Log.Error(e);
}
}
} }
} }
} }

View File

@ -1,8 +0,0 @@
namespace Wox.Infrastructure.Storage
{
public interface IStorage
{
void Load();
void Save();
}
}

View File

@ -1,50 +1,85 @@
using System.IO; using System.IO;
using System.Threading;
using Newtonsoft.Json; using Newtonsoft.Json;
using Wox.Infrastructure.Logger;
namespace Wox.Infrastructure.Storage namespace Wox.Infrastructure.Storage
{ {
/// <summary> /// <summary>
/// Serialize object using json format. /// Serialize object using json format.
/// </summary> /// </summary>
public abstract class JsonStrorage<T> : BaseStorage<T> where T : class, IStorage, new() public class JsonStrorage<T> where T : new()
{ {
private static object syncObject = new object(); private T _json;
protected override string FileSuffix private readonly JsonSerializerSettings _serializerSettings;
protected string FileName { get; set; }
protected string FilePath { get; set; }
protected const string FileSuffix = ".json";
protected string DirectoryPath { get; set; }
protected const string DirectoryName = "Config";
internal JsonStrorage()
{ {
get { return ".json"; } FileName = typeof(T).Name;
DirectoryPath = Path.Combine(WoxDirectroy.Executable, DirectoryName);
FilePath = Path.Combine(DirectoryPath, FileName + FileSuffix);
// use property initialization instead of DefaultValueAttribute
// easier and flexible for default value of object
_serializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
} }
protected override void LoadInternal() public T Load()
{ {
string json = File.ReadAllText(FilePath); if (!Directory.Exists(DirectoryPath))
if (!string.IsNullOrEmpty(json))
{ {
try Directory.CreateDirectory(DirectoryPath);
}
if (File.Exists(FilePath))
{
var searlized = File.ReadAllText(FilePath);
if (!string.IsNullOrWhiteSpace(searlized))
{ {
serializedObject = JsonConvert.DeserializeObject<T>(json); Deserialize(searlized);
} }
catch (System.Exception) else
{ {
serializedObject = LoadDefault(); LoadDefault();
} }
} }
else else
{ {
serializedObject = LoadDefault(); LoadDefault();
} }
return _json;
} }
protected override void SaveInternal() private void Deserialize(string searlized)
{ {
ThreadPool.QueueUserWorkItem(o => try
{ {
lock (syncObject) _json = JsonConvert.DeserializeObject<T>(searlized, _serializerSettings);
{ }
string json = JsonConvert.SerializeObject(serializedObject, Formatting.Indented); catch (JsonSerializationException e)
File.WriteAllText(FilePath, json); {
} LoadDefault();
}); Log.Error(e);
}
}
private void LoadDefault()
{
_json = JsonConvert.DeserializeObject<T>("{}", _serializerSettings);
Save();
}
public void Save()
{
string serialized = JsonConvert.SerializeObject(_json, Formatting.Indented);
File.WriteAllText(FilePath, serialized);
} }
} }
} }

View File

@ -0,0 +1,20 @@
using System.IO;
namespace Wox.Infrastructure.Storage
{
public class PluginSettingsStorage<T> :JsonStrorage<T> where T : new()
{
public PluginSettingsStorage()
{
var pluginDirectoryName = "Plugins";
// C# releated, add python releated below
var type = typeof (T);
FileName = type.Name;
var assemblyName = type.Assembly.GetName().Name;
DirectoryPath = Path.Combine(WoxDirectroy.Executable, DirectoryName, pluginDirectoryName, assemblyName);
FilePath = Path.Combine(DirectoryPath, FileName + FileSuffix);
}
}
}

View File

@ -63,6 +63,7 @@
<Compile Include="Hotkey\InterceptKeys.cs" /> <Compile Include="Hotkey\InterceptKeys.cs" />
<Compile Include="Hotkey\KeyEvent.cs" /> <Compile Include="Hotkey\KeyEvent.cs" />
<Compile Include="Logger\Log.cs" /> <Compile Include="Logger\Log.cs" />
<Compile Include="Storage\PluginSettingsStorage.cs" />
<Compile Include="WoxDirectroy.cs" /> <Compile Include="WoxDirectroy.cs" />
<Compile Include="Stopwatch.cs" /> <Compile Include="Stopwatch.cs" />
<Compile Include="Storage\BinaryStorage.cs" /> <Compile Include="Storage\BinaryStorage.cs" />

View File

@ -69,11 +69,6 @@ namespace Wox.Plugin
return Title + SubTitle; return Title + SubTitle;
} }
public Result()
{
}
public Result(string Title = null, string IcoPath = null, string SubTitle = null) public Result(string Title = null, string IcoPath = null, string SubTitle = null)
{ {
this.Title = Title; this.Title = Title;

View File

@ -10,9 +10,9 @@ namespace Wox
public partial class ActionKeywords : Window public partial class ActionKeywords : Window
{ {
private PluginPair _plugin; private PluginPair _plugin;
private UserSettingStorage _settings; private Settings _settings;
public ActionKeywords(string pluginId, UserSettingStorage settings) public ActionKeywords(string pluginId, Settings settings)
{ {
InitializeComponent(); InitializeComponent();
_plugin = PluginManager.GetPluginForId(pluginId); _plugin = PluginManager.GetPluginForId(pluginId);

View File

@ -9,9 +9,11 @@ using System.Windows;
using Wox.CommandArgs; using Wox.CommandArgs;
using Wox.Core.Plugin; using Wox.Core.Plugin;
using Wox.Core.Resource; using Wox.Core.Resource;
using Wox.Core.Updater;
using Wox.Core.UserSettings; using Wox.Core.UserSettings;
using Wox.Helper; using Wox.Helper;
using Wox.Infrastructure; using Wox.Infrastructure;
using Wox.Infrastructure.Storage;
using Wox.ViewModel; using Wox.ViewModel;
using Stopwatch = Wox.Infrastructure.Stopwatch; using Stopwatch = Wox.Infrastructure.Stopwatch;
@ -49,18 +51,14 @@ namespace Wox
ThreadPool.QueueUserWorkItem(_ => { ImageLoader.ImageLoader.PreloadImages(); }); ThreadPool.QueueUserWorkItem(_ => { ImageLoader.ImageLoader.PreloadImages(); });
PluginManager.Initialize(); PluginManager.Initialize();
UserSettingStorage settings = UserSettingStorage.Instance;
// happlebao temp fix for instance code logic MainViewModel mainVM = new MainViewModel();
HttpProxy.Instance.Settings = settings; API = new PublicAPIInstance(mainVM, mainVM._settings);
InternationalizationManager.Instance.Settings = settings;
ThemeManager.Instance.Settings = settings;
MainViewModel mainVM = new MainViewModel(settings);
API = new PublicAPIInstance(mainVM, settings);
PluginManager.InitializePlugins(API); PluginManager.InitializePlugins(API);
Window = new MainWindow (settings, mainVM); mainVM._settings.UpdatePluginSettings();
Window = new MainWindow (mainVM._settings, mainVM);
NotifyIconManager notifyIconManager = new NotifyIconManager(API); NotifyIconManager notifyIconManager = new NotifyIconManager(API);
CommandArgsFactory.Execute(e.Args.ToList()); CommandArgsFactory.Execute(e.Args.ToList());

View File

@ -15,9 +15,9 @@ namespace Wox
private SettingWindow _settingWidow; private SettingWindow _settingWidow;
private bool update; private bool update;
private CustomPluginHotkey updateCustomHotkey; private CustomPluginHotkey updateCustomHotkey;
private UserSettingStorage _settings; private Settings _settings;
public CustomQueryHotkeySetting(SettingWindow settingWidow, UserSettingStorage settings) public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings)
{ {
_settingWidow = settingWidow; _settingWidow = settingWidow;
InitializeComponent(); InitializeComponent();
@ -78,7 +78,6 @@ namespace Wox
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("succeed")); MessageBox.Show(InternationalizationManager.Instance.GetTranslation("succeed"));
} }
_settings.Save();
_settingWidow.ReloadCustomPluginHotkeyView(); _settingWidow.ReloadCustomPluginHotkeyView();
Close(); Close();
} }

View File

@ -6,14 +6,12 @@ using Wox.Infrastructure.Storage;
namespace Wox.ImageLoader namespace Wox.ImageLoader
{ {
[Serializable] [Serializable]
public class ImageCacheStroage : BinaryStorage<ImageCacheStroage> public class ImageCache
{ {
private int counter; private int counter;
private const int maxCached = 200; private const int maxCached = 200;
public Dictionary<string, int> TopUsedImages = new Dictionary<string, int>(); public Dictionary<string, int> TopUsedImages = new Dictionary<string, int>();
protected override string FileName { get; } = "ImageCache";
public void Add(string path) public void Add(string path)
{ {
if (TopUsedImages.ContainsKey(path)) if (TopUsedImages.ContainsKey(path))
@ -35,7 +33,6 @@ namespace Wox.ImageLoader
if (++counter == 30) if (++counter == 30)
{ {
counter = 0; counter = 0;
Save();
} }
} }

View File

@ -8,12 +8,13 @@ using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Wox.Infrastructure; using Wox.Infrastructure;
using Wox.Infrastructure.Storage;
namespace Wox.ImageLoader namespace Wox.ImageLoader
{ {
public class ImageLoader public class ImageLoader
{ {
private static readonly Dictionary<string, ImageSource> imageCache = new Dictionary<string, ImageSource>(); private static readonly Dictionary<string, ImageSource> ImageSources = new Dictionary<string, ImageSource>();
private static readonly List<string> imageExts = new List<string> private static readonly List<string> imageExts = new List<string>
{ {
@ -36,11 +37,18 @@ namespace Wox.ImageLoader
".appref-ms" ".appref-ms"
}; };
private static ImageCacheStroage _imageCache; private static readonly ImageCache _cache;
private static readonly BinaryStorage<ImageCache> _storage;
static ImageLoader() static ImageLoader()
{ {
_imageCache = ImageCacheStroage.Instance; _storage = new BinaryStorage<ImageCache>();
_cache = _storage.Load();
}
~ImageLoader()
{
_storage.Save();
} }
private static ImageSource GetIcon(string fileName) private static ImageSource GetIcon(string fileName)
@ -63,21 +71,21 @@ namespace Wox.ImageLoader
public static void PreloadImages() public static void PreloadImages()
{ {
//ImageCacheStroage.Instance.TopUsedImages can be changed during foreach, so we need to make a copy //ImageCacheStroage.Instance.TopUsedImages can be changed during foreach, so we need to make a copy
var imageList = new Dictionary<string, int>(_imageCache.TopUsedImages); var imageList = new Dictionary<string, int>(_cache.TopUsedImages);
Stopwatch.Debug($"Preload {imageList.Count} images", () => Stopwatch.Debug($"Preload {imageList.Count} images", () =>
{ {
foreach (var image in imageList) foreach (var image in imageList)
{ {
if (!imageCache.ContainsKey(image.Key)) if (!ImageSources.ContainsKey(image.Key))
{ {
ImageSource img = Load(image.Key, false); ImageSource img = Load(image.Key, false);
if (img != null) if (img != null)
{ {
img.Freeze(); //to make it copy to UI thread img.Freeze(); //to make it copy to UI thread
if (!imageCache.ContainsKey(image.Key)) if (!ImageSources.ContainsKey(image.Key))
{ {
KeyValuePair<string, int> copyedImg = image; KeyValuePair<string, int> copyedImg = image;
imageCache.Add(copyedImg.Key, img); ImageSources.Add(copyedImg.Key, img);
} }
} }
} }
@ -94,13 +102,13 @@ namespace Wox.ImageLoader
if (addToCache) if (addToCache)
{ {
_imageCache.Add(path); _cache.Add(path);
} }
if (imageCache.ContainsKey(path)) if (ImageSources.ContainsKey(path))
{ {
img = imageCache[path]; img = ImageSources[path];
} }
else else
{ {
@ -122,9 +130,9 @@ namespace Wox.ImageLoader
if (img != null && addToCache) if (img != null && addToCache)
{ {
if (!imageCache.ContainsKey(path)) if (!ImageSources.ContainsKey(path))
{ {
imageCache.Add(path, img); ImageSources.Add(path, img);
} }
} }
} }

View File

@ -15,7 +15,7 @@
<system:String x:Key="iconTrayExit">Exit</system:String> <system:String x:Key="iconTrayExit">Exit</system:String>
<!--Setting General--> <!--Setting General-->
<system:String x:Key="woxsettings">Wox Settings</system:String> <system:String x:Key="wox_settings">Wox Settings</system:String>
<system:String x:Key="general">General</system:String> <system:String x:Key="general">General</system:String>
<system:String x:Key="startWoxOnSystemStartup">Start Wox on system startup</system:String> <system:String x:Key="startWoxOnSystemStartup">Start Wox on system startup</system:String>
<system:String x:Key="hideWoxWhenLoseFocus">Hide Wox when loses focus</system:String> <system:String x:Key="hideWoxWhenLoseFocus">Hide Wox when loses focus</system:String>

View File

@ -25,11 +25,11 @@ namespace Wox
#region Private Fields #region Private Fields
private readonly Storyboard _progressBarStoryboard = new Storyboard(); private readonly Storyboard _progressBarStoryboard = new Storyboard();
private UserSettingStorage _settings; private Settings _settings;
#endregion #endregion
public MainWindow(UserSettingStorage settings, MainViewModel mainVM) public MainWindow(Settings settings, MainViewModel mainVM)
{ {
DataContext = mainVM; DataContext = mainVM;
InitializeComponent(); InitializeComponent();
@ -43,7 +43,6 @@ namespace Wox
{ {
_settings.WindowLeft = Left; _settings.WindowLeft = Left;
_settings.WindowTop = Top; _settings.WindowTop = Top;
_settings.Save();
} }
private void OnLoaded(object sender, RoutedEventArgs _) private void OnLoaded(object sender, RoutedEventArgs _)
@ -71,13 +70,12 @@ namespace Wox
QueryTextBox.Focus(); QueryTextBox.Focus();
Left = GetWindowsLeft(); Left = GetWindowsLeft();
Top = GetWindowsTop(); Top = GetWindowsTop();
_settings.IncreaseActivateTimes(); _settings.ActivateTimes++;
} }
else else
{ {
_settings.WindowLeft = Left; _settings.WindowLeft = Left;
_settings.WindowTop = Top; _settings.WindowTop = Top;
_settings.Save();
} }
}; };

View File

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> <SettingsFile xmlns="uri:_settings" CurrentProfile="(Default)">
<Profiles> <Profiles>
<Profile Name="(Default)" /> <Profile Name="(Default)" />
</Profiles> </Profiles>

View File

@ -19,10 +19,10 @@ namespace Wox
{ {
public class PublicAPIInstance : IPublicAPI public class PublicAPIInstance : IPublicAPI
{ {
private UserSettingStorage _settings; private Settings _settings;
#region Constructor #region Constructor
public PublicAPIInstance(MainViewModel mainVM, UserSettingStorage settings) public PublicAPIInstance(MainViewModel mainVM, Settings settings)
{ {
MainVM = mainVM; MainVM = mainVM;
_settings = settings; _settings = settings;

View File

@ -32,9 +32,9 @@ namespace Wox
bool settingsLoaded; bool settingsLoaded;
private Dictionary<ISettingProvider, Control> featureControls = new Dictionary<ISettingProvider, Control>(); private Dictionary<ISettingProvider, Control> featureControls = new Dictionary<ISettingProvider, Control>();
private bool themeTabLoaded; private bool themeTabLoaded;
private UserSettingStorage _settings; private Settings _settings;
public SettingWindow(IPublicAPI api, UserSettingStorage settings) public SettingWindow(IPublicAPI api, Settings settings)
{ {
InitializeComponent(); InitializeComponent();
_settings = settings; _settings = settings;
@ -49,50 +49,42 @@ namespace Wox
cbHideWhenDeactive.Checked += (o, e) => cbHideWhenDeactive.Checked += (o, e) =>
{ {
_settings.HideWhenDeactive = true; _settings.HideWhenDeactive = true;
_settings.Save();
}; };
cbHideWhenDeactive.Unchecked += (o, e) => cbHideWhenDeactive.Unchecked += (o, e) =>
{ {
_settings.HideWhenDeactive = false; _settings.HideWhenDeactive = false;
_settings.Save();
}; };
cbRememberLastLocation.Checked += (o, e) => cbRememberLastLocation.Checked += (o, e) =>
{ {
_settings.RememberLastLaunchLocation = true; _settings.RememberLastLaunchLocation = true;
_settings.Save();
}; };
cbRememberLastLocation.Unchecked += (o, e) => cbRememberLastLocation.Unchecked += (o, e) =>
{ {
_settings.RememberLastLaunchLocation = false; _settings.RememberLastLaunchLocation = false;
_settings.Save();
}; };
cbDontPromptUpdateMsg.Checked += (o, e) => cbDontPromptUpdateMsg.Checked += (o, e) =>
{ {
_settings.DontPromptUpdateMsg = true; _settings.DontPromptUpdateMsg = true;
_settings.Save();
}; };
cbDontPromptUpdateMsg.Unchecked += (o, e) => cbDontPromptUpdateMsg.Unchecked += (o, e) =>
{ {
_settings.DontPromptUpdateMsg = false; _settings.DontPromptUpdateMsg = false;
_settings.Save();
}; };
cbIgnoreHotkeysOnFullscreen.Checked += (o, e) => cbIgnoreHotkeysOnFullscreen.Checked += (o, e) =>
{ {
_settings.IgnoreHotkeysOnFullscreen = true; _settings.IgnoreHotkeysOnFullscreen = true;
_settings.Save();
}; };
cbIgnoreHotkeysOnFullscreen.Unchecked += (o, e) => cbIgnoreHotkeysOnFullscreen.Unchecked += (o, e) =>
{ {
_settings.IgnoreHotkeysOnFullscreen = false; _settings.IgnoreHotkeysOnFullscreen = false;
_settings.Save();
}; };
@ -100,7 +92,6 @@ namespace Wox
comboMaxResultsToShow.SelectionChanged += (o, e) => comboMaxResultsToShow.SelectionChanged += (o, e) =>
{ {
_settings.MaxResultsToShow = (int)comboMaxResultsToShow.SelectedItem; _settings.MaxResultsToShow = (int)comboMaxResultsToShow.SelectedItem;
_settings.Save();
//MainWindow.pnlResult.lbResults.GetBindingExpression(MaxHeightProperty).UpdateTarget(); //MainWindow.pnlResult.lbResults.GetBindingExpression(MaxHeightProperty).UpdateTarget();
}; };
@ -215,14 +206,12 @@ namespace Wox
{ {
AddApplicationToStartup(); AddApplicationToStartup();
_settings.StartWoxOnSystemStartup = true; _settings.StartWoxOnSystemStartup = true;
_settings.Save();
} }
private void CbStartWithWindows_OnUnchecked(object sender, RoutedEventArgs e) private void CbStartWithWindows_OnUnchecked(object sender, RoutedEventArgs e)
{ {
RemoveApplicationFromStartup(); RemoveApplicationFromStartup();
_settings.StartWoxOnSystemStartup = false; _settings.StartWoxOnSystemStartup = false;
_settings.Save();
} }
private void AddApplicationToStartup() private void AddApplicationToStartup()
@ -270,7 +259,6 @@ namespace Wox
}); });
RemoveHotkey(_settings.Hotkey); RemoveHotkey(_settings.Hotkey);
_settings.Hotkey = ctlHotkey.CurrentHotkey.ToString(); _settings.Hotkey = ctlHotkey.CurrentHotkey.ToString();
_settings.Save();
} }
} }
@ -317,7 +305,6 @@ namespace Wox
{ {
_settings.CustomPluginHotkeys.Remove(item); _settings.CustomPluginHotkeys.Remove(item);
lvCustomHotkey.Items.Refresh(); lvCustomHotkey.Items.Refresh();
_settings.Save();
RemoveHotkey(item.Hotkey); RemoveHotkey(item.Hotkey);
} }
} }
@ -481,7 +468,6 @@ namespace Wox
string queryBoxFontName = cbQueryBoxFont.SelectedItem.ToString(); string queryBoxFontName = cbQueryBoxFont.SelectedItem.ToString();
_settings.QueryBoxFont = queryBoxFontName; _settings.QueryBoxFont = queryBoxFontName;
cbQueryBoxFontFaces.SelectedItem = ((FontFamily)cbQueryBoxFont.SelectedItem).ChooseRegularFamilyTypeface(); cbQueryBoxFontFaces.SelectedItem = ((FontFamily)cbQueryBoxFont.SelectedItem).ChooseRegularFamilyTypeface();
_settings.Save();
ThemeManager.Instance.ChangeTheme(_settings.Theme); ThemeManager.Instance.ChangeTheme(_settings.Theme);
} }
@ -499,7 +485,6 @@ namespace Wox
_settings.QueryBoxFontStretch = typeface.Stretch.ToString(); _settings.QueryBoxFontStretch = typeface.Stretch.ToString();
_settings.QueryBoxFontWeight = typeface.Weight.ToString(); _settings.QueryBoxFontWeight = typeface.Weight.ToString();
_settings.QueryBoxFontStyle = typeface.Style.ToString(); _settings.QueryBoxFontStyle = typeface.Style.ToString();
_settings.Save();
ThemeManager.Instance.ChangeTheme(_settings.Theme); ThemeManager.Instance.ChangeTheme(_settings.Theme);
} }
} }
@ -510,7 +495,6 @@ namespace Wox
string resultItemFont = ResultFontComboBox.SelectedItem.ToString(); string resultItemFont = ResultFontComboBox.SelectedItem.ToString();
_settings.ResultFont = resultItemFont; _settings.ResultFont = resultItemFont;
ResultFontFacesComboBox.SelectedItem = ((FontFamily)ResultFontComboBox.SelectedItem).ChooseRegularFamilyTypeface(); ResultFontFacesComboBox.SelectedItem = ((FontFamily)ResultFontComboBox.SelectedItem).ChooseRegularFamilyTypeface();
_settings.Save();
ThemeManager.Instance.ChangeTheme(_settings.Theme); ThemeManager.Instance.ChangeTheme(_settings.Theme);
} }
@ -528,7 +512,6 @@ namespace Wox
_settings.ResultFontStretch = typeface.Stretch.ToString(); _settings.ResultFontStretch = typeface.Stretch.ToString();
_settings.ResultFontWeight = typeface.Weight.ToString(); _settings.ResultFontWeight = typeface.Weight.ToString();
_settings.ResultFontStyle = typeface.Style.ToString(); _settings.ResultFontStyle = typeface.Style.ToString();
_settings.Save();
ThemeManager.Instance.ChangeTheme(_settings.Theme); ThemeManager.Instance.ChangeTheme(_settings.Theme);
} }
} }
@ -569,7 +552,7 @@ namespace Wox
pluginId = pair.Metadata.ID; pluginId = pair.Metadata.ID;
pluginIcon.Source = ImageLoader.ImageLoader.Load(pair.Metadata.FullIcoPath); pluginIcon.Source = ImageLoader.ImageLoader.Load(pair.Metadata.FullIcoPath);
var customizedPluginConfig = _settings.CustomizedPluginConfigs[pluginId]; var customizedPluginConfig = _settings.PluginSettings[pluginId];
cbDisablePlugin.IsChecked = customizedPluginConfig != null && customizedPluginConfig.Disabled; cbDisablePlugin.IsChecked = customizedPluginConfig != null && customizedPluginConfig.Disabled;
PluginContentPanel.Content = null; PluginContentPanel.Content = null;
@ -609,31 +592,19 @@ namespace Wox
if (cbDisabled == null) return; if (cbDisabled == null) return;
var pair = lbPlugins.SelectedItem as PluginPair; var pair = lbPlugins.SelectedItem as PluginPair;
var id = string.Empty;
var name = string.Empty;
if (pair != null) if (pair != null)
{ {
//third-party plugin var id = pair.Metadata.ID;
id = pair.Metadata.ID; var customizedPluginConfig = _settings.PluginSettings[id];
name = pair.Metadata.Name; if (customizedPluginConfig.Disabled)
}
var customizedPluginConfig = _settings.CustomizedPluginConfigs[id];
if (customizedPluginConfig == null)
{
// todo when this part will be invoked
_settings.CustomizedPluginConfigs[id] = new CustomizedPluginConfig
{ {
Disabled = cbDisabled.IsChecked ?? true, PluginManager.DisablePlugin(pair);
ID = id, }
Name = name, else
ActionKeywords = null {
}; PluginManager.EnablePlugin(pair);
}
} }
else
{
customizedPluginConfig.Disabled = cbDisabled.IsChecked ?? true;
}
_settings.Save();
} }
private void PluginActionKeywords_OnMouseUp(object sender, MouseButtonEventArgs e) private void PluginActionKeywords_OnMouseUp(object sender, MouseButtonEventArgs e)
@ -744,7 +715,6 @@ namespace Wox
_settings.ProxyPort = port; _settings.ProxyPort = port;
_settings.ProxyUserName = tbProxyUserName.Text; _settings.ProxyUserName = tbProxyUserName.Text;
_settings.ProxyPassword = tbProxyPassword.Password; _settings.ProxyPassword = tbProxyPassword.Password;
_settings.Save();
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("saveProxySuccessfully")); MessageBox.Show(InternationalizationManager.Instance.GetTranslation("saveProxySuccessfully"));
} }

View File

@ -7,10 +7,9 @@ using Wox.Plugin;
namespace Wox.Storage namespace Wox.Storage
{ {
public class QueryHistoryStorage : JsonStrorage<QueryHistoryStorage> public class QueryHistory
{ {
[JsonProperty] public List<HistoryItem> History = new List<HistoryItem>();
private List<HistoryItem> History = new List<HistoryItem>();
private int MaxHistory = 300; private int MaxHistory = 300;
private int cursor; private int cursor;
@ -18,8 +17,6 @@ namespace Wox.Storage
public static PluginMetadata MetaData { get; } = new PluginMetadata public static PluginMetadata MetaData { get; } = new PluginMetadata
{ ID = "Query history", Name = "Query history" }; { ID = "Query history", Name = "Query history" };
protected override string FileName { get; } = "QueryHistory";
public HistoryItem Previous() public HistoryItem Previous()
{ {
if (History.Count == 0 || cursor == 0) return null; if (History.Count == 0 || cursor == 0) return null;
@ -58,11 +55,6 @@ namespace Wox.Storage
}); });
} }
if (History.Count % 5 == 0)
{
Save();
}
Reset(); Reset();
} }

View File

@ -5,11 +5,9 @@ using Wox.Plugin;
namespace Wox.Storage namespace Wox.Storage
{ {
public class TopMostRecordStorage : JsonStrorage<TopMostRecordStorage> public class TopMostRecord
{ {
public Dictionary<string, TopMostRecord> records = new Dictionary<string, TopMostRecord>(); public Dictionary<string, Record> records = new Dictionary<string, Record>();
protected override string FileName { get; } = "TopMostRecords";
internal bool IsTopMost(Result result) internal bool IsTopMost(Result result)
{ {
@ -24,7 +22,6 @@ namespace Wox.Storage
if (records.ContainsKey(result.OriginQuery.RawQuery)) if (records.ContainsKey(result.OriginQuery.RawQuery))
{ {
records.Remove(result.OriginQuery.RawQuery); records.Remove(result.OriginQuery.RawQuery);
Save();
} }
} }
@ -38,20 +35,18 @@ namespace Wox.Storage
} }
else else
{ {
records.Add(result.OriginQuery.RawQuery, new TopMostRecord records.Add(result.OriginQuery.RawQuery, new Record
{ {
PluginID = result.PluginID, PluginID = result.PluginID,
Title = result.Title, Title = result.Title,
SubTitle = result.SubTitle SubTitle = result.SubTitle
}); });
} }
Save();
} }
} }
public class TopMostRecord public class Record
{ {
public string Title { get; set; } public string Title { get; set; }
public string SubTitle { get; set; } public string SubTitle { get; set; }

View File

@ -5,13 +5,11 @@ using Wox.Plugin;
namespace Wox.Storage namespace Wox.Storage
{ {
public class UserSelectedRecordStorage : JsonStrorage<UserSelectedRecordStorage> public class UserSelectedRecord
{ {
[JsonProperty] [JsonProperty]
private Dictionary<string, int> records = new Dictionary<string, int>(); private Dictionary<string, int> records = new Dictionary<string, int>();
protected override string FileName { get; } = "UserSelectedRecords";
public void Add(Result result) public void Add(Result result)
{ {
if (records.ContainsKey(result.ToString())) if (records.ContainsKey(result.ToString()))
@ -22,7 +20,6 @@ namespace Wox.Storage
{ {
records.Add(result.ToString(), 1); records.Add(result.ToString(), 1);
} }
Save();
} }
public int GetSelectedCount(Result result) public int GetSelectedCount(Result result)

View File

@ -7,10 +7,12 @@ using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using Wox.Core.Plugin; using Wox.Core.Plugin;
using Wox.Core.Resource; using Wox.Core.Resource;
using Wox.Core.Updater;
using Wox.Core.UserSettings; using Wox.Core.UserSettings;
using Wox.Helper; using Wox.Helper;
using Wox.Infrastructure; using Wox.Infrastructure;
using Wox.Infrastructure.Hotkey; using Wox.Infrastructure.Hotkey;
using Wox.Infrastructure.Storage;
using Wox.Plugin; using Wox.Plugin;
using Wox.Storage; using Wox.Storage;
using Stopwatch = Wox.Infrastructure.Stopwatch; using Stopwatch = Wox.Infrastructure.Stopwatch;
@ -36,24 +38,41 @@ namespace Wox.ViewModel
private string _queryTextBeforeLoadContextMenu; private string _queryTextBeforeLoadContextMenu;
private string _queryText; private string _queryText;
private UserSettingStorage _settings; private readonly JsonStrorage<Settings> _settingsStorage;
private QueryHistoryStorage _queryHistory; private readonly JsonStrorage<QueryHistory> _queryHistoryStorage;
private UserSelectedRecordStorage _userSelectedRecord; private readonly JsonStrorage<UserSelectedRecord> _userSelectedRecordStorage;
private TopMostRecordStorage _topMostRecord; private readonly JsonStrorage<TopMostRecord> _topMostRecordStorage;
// todo happlebao this field should be private in the future
public readonly Settings _settings;
private readonly QueryHistory _queryHistory;
private readonly UserSelectedRecord _userSelectedRecord;
private readonly TopMostRecord _topMostRecord;
#endregion #endregion
#region Constructor #region Constructor
public MainViewModel(UserSettingStorage settings) public MainViewModel()
{ {
_queryTextBeforeLoadContextMenu = ""; _queryTextBeforeLoadContextMenu = "";
_queryText = ""; _queryText = "";
_lastQuery = new Query(); _lastQuery = new Query();
_settings = settings;
_queryHistory = QueryHistoryStorage.Instance; _settingsStorage = new JsonStrorage<Settings>();
_userSelectedRecord = UserSelectedRecordStorage.Instance; _settings = _settingsStorage.Load();
_topMostRecord = TopMostRecordStorage.Instance;
// happlebao todo temp fix for instance code logic
HttpProxy.Instance.Settings = _settings;
UpdaterManager.Instance.Settings = _settings;
InternationalizationManager.Instance.Settings = _settings;
ThemeManager.Instance.Settings = _settings;
_queryHistoryStorage = new JsonStrorage<QueryHistory>();
_userSelectedRecordStorage = new JsonStrorage<UserSelectedRecord>();
_topMostRecordStorage = new JsonStrorage<TopMostRecord>();
_queryHistory = _queryHistoryStorage.Load();
_userSelectedRecord = _userSelectedRecordStorage.Load();
_topMostRecord = _topMostRecordStorage.Load();
InitializeResultListBox(); InitializeResultListBox();
InitializeContextMenu(); InitializeContextMenu();
@ -61,9 +80,12 @@ namespace Wox.ViewModel
} }
public MainViewModel() ~MainViewModel()
{ {
_settingsStorage.Save();
_queryHistoryStorage.Save();
_userSelectedRecordStorage.Save();
_topMostRecordStorage.Save();
} }
#endregion #endregion
@ -433,7 +455,7 @@ namespace Wox.ViewModel
var plugins = PluginManager.ValidPluginsForQuery(query); var plugins = PluginManager.ValidPluginsForQuery(query);
foreach (var plugin in plugins) foreach (var plugin in plugins)
{ {
var config = _settings.CustomizedPluginConfigs[plugin.Metadata.ID]; var config = _settings.PluginSettings[plugin.Metadata.ID];
if (!config.Disabled) if (!config.Disabled)
{ {
ThreadPool.QueueUserWorkItem(o => ThreadPool.QueueUserWorkItem(o =>
@ -450,7 +472,7 @@ namespace Wox.ViewModel
private void ResetQueryHistoryIndex() private void ResetQueryHistoryIndex()
{ {
Results.RemoveResultsFor(QueryHistoryStorage.MetaData); Results.RemoveResultsFor(QueryHistory.MetaData);
_queryHistory.Reset(); _queryHistory.Reset();
} }
@ -464,7 +486,7 @@ namespace Wox.ViewModel
{ {
if (history != null) if (history != null)
{ {
var historyMetadata = QueryHistoryStorage.MetaData; var historyMetadata = QueryHistory.MetaData;
QueryText = history.Query; QueryText = history.Query;
OnTextBoxSelected(); OnTextBoxSelected();

View File

@ -37,6 +37,25 @@ namespace Wox.ViewModel
public string FullIcoPath => RawResult.FullIcoPath; public string FullIcoPath => RawResult.FullIcoPath;
public string PluginID => RawResult.PluginID;
public int Score
{
get { return RawResult.Score; }
set { RawResult.Score = value; }
}
public Query OriginQuery
{
get { return RawResult.OriginQuery; }
set { RawResult.OriginQuery = value; }
}
public Func<ActionContext, bool> Action
{
get { return RawResult.Action; }
set { RawResult.Action = value; }
}
public bool IsSelected public bool IsSelected
{ {
get { return _isSelected; } get { return _isSelected; }
@ -51,10 +70,16 @@ namespace Wox.ViewModel
#region Properties #region Properties
public Result RawResult { get; } internal Result RawResult { get; }
#endregion #endregion
public void Update(ResultViewModel newResult)
{
RawResult.Score = newResult.RawResult.Score;
RawResult.OriginQuery = newResult.RawResult.OriginQuery;
}
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
ResultViewModel r = obj as ResultViewModel; ResultViewModel r = obj as ResultViewModel;

View File

@ -20,10 +20,10 @@ namespace Wox.ViewModel
private Thickness _margin; private Thickness _margin;
private readonly object _resultsUpdateLock = new object(); private readonly object _resultsUpdateLock = new object();
private UserSettingStorage _settings; private Settings _settings;
private TopMostRecordStorage _topMostRecord; private TopMostRecord _topMostRecord;
public ResultsViewModel(UserSettingStorage settings, TopMostRecordStorage topMostRecord) public ResultsViewModel(Settings settings, TopMostRecord topMostRecord)
{ {
_settings = settings; _settings = settings;
_topMostRecord = topMostRecord; _topMostRecord = topMostRecord;
@ -191,7 +191,7 @@ namespace Wox.ViewModel
{ {
lock (_resultsUpdateLock) lock (_resultsUpdateLock)
{ {
Results.RemoveAll(r => r.RawResult.PluginID == metadata.ID); Results.RemoveAll(r => r.PluginID == metadata.ID);
} }
} }
@ -202,7 +202,7 @@ namespace Wox.ViewModel
var newResults = newRawResults.Select(r => new ResultViewModel(r)).ToList(); var newResults = newRawResults.Select(r => new ResultViewModel(r)).ToList();
// todo use async to do new result calculation // todo use async to do new result calculation
var resultsCopy = Results.ToList(); var resultsCopy = Results.ToList();
var oldResults = resultsCopy.Where(r => r.RawResult.PluginID == resultId).ToList(); var oldResults = resultsCopy.Where(r => r.PluginID == resultId).ToList();
// intersection of A (old results) and B (new newResults) // intersection of A (old results) and B (new newResults)
var intersection = oldResults.Intersect(newResults).ToList(); var intersection = oldResults.Intersect(newResults).ToList();
// remove result of relative complement of B in A // remove result of relative complement of B in A
@ -216,7 +216,7 @@ namespace Wox.ViewModel
{ {
if (IsTopMostResult(result.RawResult)) if (IsTopMostResult(result.RawResult))
{ {
result.RawResult.Score = int.MaxValue; result.Score = int.MaxValue;
} }
} }
@ -224,23 +224,26 @@ namespace Wox.ViewModel
foreach (var commonResult in intersection) foreach (var commonResult in intersection)
{ {
int oldIndex = resultsCopy.IndexOf(commonResult); int oldIndex = resultsCopy.IndexOf(commonResult);
int oldScore = resultsCopy[oldIndex].RawResult.Score; int oldScore = resultsCopy[oldIndex].Score;
int newScore = newResults[newResults.IndexOf(commonResult)].RawResult.Score; var newResult = newResults[newResults.IndexOf(commonResult)];
int newScore = newResult.Score;
if (newScore != oldScore) if (newScore != oldScore)
{ {
var oldResult = resultsCopy[oldIndex]; var oldResult = resultsCopy[oldIndex];
oldResult.RawResult.Score = newScore;
oldResult.Score = newScore;
oldResult.OriginQuery = newResult.OriginQuery;
resultsCopy.RemoveAt(oldIndex); resultsCopy.RemoveAt(oldIndex);
int newIndex = InsertIndexOf(newScore, resultsCopy); int newIndex = InsertIndexOf(newScore, resultsCopy);
resultsCopy.Insert(newIndex, oldResult); resultsCopy.Insert(newIndex, oldResult);
} }
} }
// insert result in relative complement of A in B // insert result in relative complement of A in B
foreach (var result in newResults.Except(intersection)) foreach (var result in newResults.Except(intersection))
{ {
int newIndex = InsertIndexOf(result.RawResult.Score, resultsCopy); int newIndex = InsertIndexOf(result.Score, resultsCopy);
resultsCopy.Insert(newIndex, result); resultsCopy.Insert(newIndex, result);
} }
@ -299,9 +302,9 @@ namespace Wox.ViewModel
{ {
this[i] = newResult; this[i] = newResult;
} }
else if (oldResult.RawResult.Score != newResult.RawResult.Score) else if (oldResult.Score != newResult.Score)
{ {
this[i].RawResult.Score = newResult.RawResult.Score; this[i].Score = newResult.Score;
} }
} }