mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-14 19:49:15 +08:00
Merge pull request #31 from jjw24/enable_userselected_programloading
Enable users to configure what programs to load
This commit is contained in:
commit
15eca63ff0
@ -1,6 +1,8 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using Wox.Plugin.Program.Programs;
|
||||
using Wox.Plugin.Program.Views.Models;
|
||||
using Wox.Plugin.Program.Views;
|
||||
using System.Linq;
|
||||
|
||||
namespace Wox.Plugin.Program
|
||||
{
|
||||
@ -50,11 +52,17 @@ namespace Wox.Plugin.Program
|
||||
}
|
||||
if (_editing == null)
|
||||
{
|
||||
var source = new Settings.ProgramSource
|
||||
if (!ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == Directory.Text))
|
||||
{
|
||||
Location = Directory.Text,
|
||||
};
|
||||
_settings.ProgramSources.Add(source);
|
||||
var source = new ProgramSource
|
||||
{
|
||||
Location = Directory.Text,
|
||||
UniqueIdentifier = Directory.Text
|
||||
};
|
||||
|
||||
_settings.ProgramSources.Insert(0, source);
|
||||
ProgramSetting.ProgramSettingDisplayList.Add(source);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
BIN
Plugins/Wox.Plugin.Program/Images/disable.png
Normal file
BIN
Plugins/Wox.Plugin.Program/Images/disable.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
@ -21,7 +21,6 @@
|
||||
<system:String x:Key="wox_plugin_program_max_search_depth">Maximale Suchtiefe (-1 ist unlimitiert):</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_pls_select_program_source">Bitte wähle eine Programmquelle</system:String>
|
||||
<system:String x:Key="wox_plugin_program_delete_program_source">Willst du wirklich {0} löschen?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_update">Aktualisieren</system:String>
|
||||
<system:String x:Key="wox_plugin_program_only_index_tip">Wox indexiert nur Datien mit folgenden Endungen:</system:String>
|
||||
|
@ -6,8 +6,10 @@
|
||||
<system:String x:Key="wox_plugin_program_delete">Delete</system:String>
|
||||
<system:String x:Key="wox_plugin_program_edit">Edit</system:String>
|
||||
<system:String x:Key="wox_plugin_program_add">Add</system:String>
|
||||
<system:String x:Key="wox_plugin_program_disable">Disable</system:String>
|
||||
<system:String x:Key="wox_plugin_program_location">Location</system:String>
|
||||
<system:String x:Key="wox_plugin_program_suffixes">Index file suffixes</system:String>
|
||||
<system:String x:Key="wox_plugin_program_all_programs">All Programs</system:String>
|
||||
<system:String x:Key="wox_plugin_program_suffixes">File Suffixes</system:String>
|
||||
<system:String x:Key="wox_plugin_program_reindex">Reindex</system:String>
|
||||
<system:String x:Key="wox_plugin_program_indexing">Indexing</system:String>
|
||||
<system:String x:Key="wox_plugin_program_index_start">Index Start Menu</system:String>
|
||||
@ -21,20 +23,25 @@
|
||||
<system:String x:Key="wox_plugin_program_max_search_depth">Maximum Search Depth (-1 is unlimited):</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_pls_select_program_source">Please select a program source</system:String>
|
||||
<system:String x:Key="wox_plugin_program_delete_program_source">Are you sure you want to delete {0}?</system:String>
|
||||
<system:String x:Key="wox_plugin_program_delete_program_source">Are you sure you want to delete the selected program sources?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_update">Update</system:String>
|
||||
<system:String x:Key="wox_plugin_program_only_index_tip">Wox will only index files that end with the following suffixes:</system:String>
|
||||
<system:String x:Key="wox_plugin_program_split_by_tip">(Each suffix should split by ;)</system:String>
|
||||
<system:String x:Key="wox_plugin_program_split_by_tip">(Each suffix should split by ';' )</system:String>
|
||||
<system:String x:Key="wox_plugin_program_update_file_suffixes">Successfully updated file suffixes</system:String>
|
||||
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">File suffixes can't be empty</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_run_as_administrator">Run As Administrator</system:String>
|
||||
<system:String x:Key="wox_plugin_program_open_containing_folder">Open containing folder</system:String>
|
||||
<system:String x:Key="wox_plugin_program_disable_program">Disable this program from displaying</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_plugin_name">Program</system:String>
|
||||
<system:String x:Key="wox_plugin_program_plugin_description">Search programs in Wox</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_invalid_path">Invalid Path</system:String>
|
||||
|
||||
<!--Dialogs-->
|
||||
<system:String x:Key="wox_plugin_program_disable_dlgtitle_success">Success</system:String>
|
||||
<system:String x:Key="wox_plugin_program_disable_dlgtitle_success_message">Successfully disabled this program from displaying in your query</system:String>
|
||||
|
||||
</ResourceDictionary>
|
@ -21,7 +21,6 @@
|
||||
<system:String x:Key="wox_plugin_program_max_search_depth">Maksymalna głębokość wyszukiwania (-1 to nieograniczona):</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_pls_select_program_source">Musisz wybrać katalog programu</system:String>
|
||||
<system:String x:Key="wox_plugin_program_delete_program_source">Czy jesteś pewien że chcesz usunąć {0}?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_update">Aktualizuj</system:String>
|
||||
<system:String x:Key="wox_plugin_program_only_index_tip">Wox będzie indeksował tylko te pliki z podanymi rozszerzeniami:</system:String>
|
||||
|
@ -21,7 +21,6 @@
|
||||
<system:String x:Key="wox_plugin_program_max_search_depth">Maksimum Arama Derinliği (Limitsiz için -1):</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_pls_select_program_source">İşlem yapmak istediğiniz klasörü seçin.</system:String>
|
||||
<system:String x:Key="wox_plugin_program_delete_program_source">{0} klasörünü silmek istediğinize emin misiniz?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_update">Güncelle</system:String>
|
||||
<system:String x:Key="wox_plugin_program_only_index_tip">Wox yalnızca aşağıdaki uzantılara sahip dosyaları indeksleyecektir:</system:String>
|
||||
|
@ -21,7 +21,6 @@
|
||||
<system:String x:Key="wox_plugin_program_max_search_depth">最大搜索深度(-1是无限的):</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_pls_select_program_source">请先选择一项</system:String>
|
||||
<system:String x:Key="wox_plugin_program_delete_program_source">你确定要删除{0}吗?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_update">更新</system:String>
|
||||
<system:String x:Key="wox_plugin_program_only_index_tip">Wox仅索引下列后缀的文件:</system:String>
|
||||
|
@ -21,7 +21,6 @@
|
||||
<system:String x:Key="wox_plugin_program_max_search_depth">最大搜尋深度(-1是無限的):</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_pls_select_program_source">請先選擇一項</system:String>
|
||||
<system:String x:Key="wox_plugin_program_delete_program_source">你確定要刪除{0}嗎?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_program_update">更新</system:String>
|
||||
<system:String x:Key="wox_plugin_program_only_index_tip">Wox 僅索引下列副檔名的檔案:</system:String>
|
||||
|
@ -1,14 +1,13 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Infrastructure.Logger;
|
||||
using Wox.Infrastructure.Storage;
|
||||
using Wox.Plugin.Program.Programs;
|
||||
using Wox.Plugin.Program.Views;
|
||||
using Stopwatch = Wox.Infrastructure.Stopwatch;
|
||||
|
||||
namespace Wox.Plugin.Program
|
||||
@ -16,14 +15,16 @@ namespace Wox.Plugin.Program
|
||||
public class Main : ISettingProvider, IPlugin, IPluginI18n, IContextMenu, ISavable, IReloadable
|
||||
{
|
||||
private static readonly object IndexLock = new object();
|
||||
private static Win32[] _win32s;
|
||||
private static UWP.Application[] _uwps;
|
||||
internal static Win32[] _win32s { get; set; }
|
||||
internal static UWP.Application[] _uwps { get; set; }
|
||||
internal static Settings _settings { get; set; }
|
||||
|
||||
private static bool IsStartupIndexProgramsRequired => _settings.LastIndexTime.AddDays(3) < DateTime.Today;
|
||||
|
||||
private static PluginInitContext _context;
|
||||
|
||||
private static BinaryStorage<Win32[]> _win32Storage;
|
||||
private static BinaryStorage<UWP.Application[]> _uwpStorage;
|
||||
private static Settings _settings;
|
||||
private static BinaryStorage<UWP.Application[]> _uwpStorage;
|
||||
private readonly PluginJsonStorage<Settings> _settingsStorage;
|
||||
|
||||
public Main()
|
||||
@ -40,10 +41,22 @@ namespace Wox.Plugin.Program
|
||||
});
|
||||
Log.Info($"|Wox.Plugin.Program.Main|Number of preload win32 programs <{_win32s.Length}>");
|
||||
Log.Info($"|Wox.Plugin.Program.Main|Number of preload uwps <{_uwps.Length}>");
|
||||
Task.Run(() =>
|
||||
|
||||
var a = Task.Run(() =>
|
||||
{
|
||||
Stopwatch.Normal("|Wox.Plugin.Program.Main|Program index cost", IndexPrograms);
|
||||
if (IsStartupIndexProgramsRequired || !_win32s.Any())
|
||||
Stopwatch.Normal("|Wox.Plugin.Program.Main|Win32Program index cost", IndexWin32Programs);
|
||||
});
|
||||
|
||||
var b = Task.Run(() =>
|
||||
{
|
||||
if (IsStartupIndexProgramsRequired || !_uwps.Any())
|
||||
Stopwatch.Normal("|Wox.Plugin.Program.Main|Win32Program index cost", IndexUWPPrograms);
|
||||
});
|
||||
|
||||
Task.WaitAll(a, b);
|
||||
|
||||
_settings.LastIndexTime = DateTime.Today;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
@ -57,8 +70,14 @@ namespace Wox.Plugin.Program
|
||||
{
|
||||
lock (IndexLock)
|
||||
{
|
||||
var results1 = _win32s.AsParallel().Select(p => p.Result(query.Search, _context.API));
|
||||
var results2 = _uwps.AsParallel().Select(p => p.Result(query.Search, _context.API));
|
||||
var results1 = _win32s.AsParallel()
|
||||
.Where(p => p.Enabled)
|
||||
.Select(p => p.Result(query.Search, _context.API));
|
||||
|
||||
var results2 = _uwps.AsParallel()
|
||||
.Where(p => p.Enabled)
|
||||
.Select(p => p.Result(query.Search, _context.API));
|
||||
|
||||
var result = results1.Concat(results2).Where(r => r.Score > 0).ToList();
|
||||
return result;
|
||||
}
|
||||
@ -69,39 +88,39 @@ namespace Wox.Plugin.Program
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public static void IndexPrograms()
|
||||
public static void IndexWin32Programs()
|
||||
{
|
||||
Win32[] w = { };
|
||||
UWP.Application[] u = { };
|
||||
var t1 = Task.Run(() =>
|
||||
{
|
||||
w = Win32.All(_settings);
|
||||
});
|
||||
var t2 = Task.Run(() =>
|
||||
{
|
||||
var windows10 = new Version(10, 0);
|
||||
var support = Environment.OSVersion.Version.Major >= windows10.Major;
|
||||
if (support)
|
||||
{
|
||||
u = UWP.All();
|
||||
}
|
||||
else
|
||||
{
|
||||
u = new UWP.Application[] { };
|
||||
}
|
||||
});
|
||||
Task.WaitAll(t1, t2);
|
||||
|
||||
lock (IndexLock)
|
||||
{
|
||||
_win32s = w;
|
||||
_uwps = u;
|
||||
_win32s = Win32.All(_settings);
|
||||
}
|
||||
}
|
||||
|
||||
public static void IndexUWPPrograms()
|
||||
{
|
||||
var windows10 = new Version(10, 0);
|
||||
var support = Environment.OSVersion.Version.Major >= windows10.Major;
|
||||
|
||||
lock (IndexLock)
|
||||
{
|
||||
_uwps = support ? UWP.All() : new UWP.Application[] { };
|
||||
}
|
||||
}
|
||||
|
||||
public static void IndexPrograms()
|
||||
{
|
||||
var t1 = Task.Run(() => { IndexWin32Programs(); });
|
||||
|
||||
var t2 = Task.Run(() => { IndexUWPPrograms(); });
|
||||
|
||||
Task.WaitAll(t1, t2);
|
||||
|
||||
_settings.LastIndexTime = DateTime.Today;
|
||||
}
|
||||
|
||||
public Control CreateSettingPanel()
|
||||
{
|
||||
return new ProgramSetting(_context, _settings);
|
||||
return new ProgramSetting(_context, _settings, _win32s, _uwps);
|
||||
}
|
||||
|
||||
public string GetTranslatedPluginTitle()
|
||||
@ -116,16 +135,52 @@ namespace Wox.Plugin.Program
|
||||
|
||||
public List<Result> LoadContextMenus(Result selectedResult)
|
||||
{
|
||||
var menuOptions = new List<Result>();
|
||||
var program = selectedResult.ContextData as IProgram;
|
||||
if (program != null)
|
||||
{
|
||||
var menus = program.ContextMenus(_context.API);
|
||||
return menus;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<Result>();
|
||||
menuOptions = program.ContextMenus(_context.API);
|
||||
}
|
||||
|
||||
menuOptions.Add(
|
||||
new Result
|
||||
{
|
||||
Title = _context.API.GetTranslation("wox_plugin_program_disable_program"),
|
||||
Action = c =>
|
||||
{
|
||||
DisableProgram(program);
|
||||
_context.API.ShowMsg(_context.API.GetTranslation("wox_plugin_program_disable_dlgtitle_success"),
|
||||
_context.API.GetTranslation("wox_plugin_program_disable_dlgtitle_success_message"));
|
||||
return false;
|
||||
},
|
||||
IcoPath = "Images/disable.png"
|
||||
}
|
||||
);
|
||||
|
||||
return menuOptions;
|
||||
}
|
||||
|
||||
private void DisableProgram(IProgram programToDelete)
|
||||
{
|
||||
if (_settings.DisabledProgramSources.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
|
||||
return;
|
||||
|
||||
if (_uwps.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
|
||||
_uwps.Where(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier).FirstOrDefault().Enabled = false;
|
||||
|
||||
if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
|
||||
_win32s.Where(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier).FirstOrDefault().Enabled = false;
|
||||
|
||||
_settings.DisabledProgramSources
|
||||
.Add(
|
||||
new Settings.DisabledProgramSource
|
||||
{
|
||||
Name = programToDelete.Name,
|
||||
Location = programToDelete.Location,
|
||||
UniqueIdentifier = programToDelete.UniqueIdentifier,
|
||||
Enabled = false
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public static bool StartProcess(ProcessStartInfo info)
|
||||
|
@ -1,149 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Wox.Plugin.Program.Programs;
|
||||
|
||||
namespace Wox.Plugin.Program
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ProgramSetting.xaml
|
||||
/// </summary>
|
||||
public partial class ProgramSetting : UserControl
|
||||
{
|
||||
private PluginInitContext context;
|
||||
private Settings _settings;
|
||||
|
||||
public ProgramSetting(PluginInitContext context, Settings settings)
|
||||
{
|
||||
this.context = context;
|
||||
InitializeComponent();
|
||||
Loaded += Setting_Loaded;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
private void Setting_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
programSourceView.ItemsSource = _settings.ProgramSources;
|
||||
StartMenuEnabled.IsChecked = _settings.EnableStartMenuSource;
|
||||
RegistryEnabled.IsChecked = _settings.EnableRegistrySource;
|
||||
}
|
||||
|
||||
private void ReIndexing()
|
||||
{
|
||||
programSourceView.Items.Refresh();
|
||||
Task.Run(() =>
|
||||
{
|
||||
Dispatcher.Invoke(() => { indexingPanel.Visibility = Visibility.Visible; });
|
||||
Main.IndexPrograms();
|
||||
Dispatcher.Invoke(() => { indexingPanel.Visibility = Visibility.Hidden; });
|
||||
});
|
||||
}
|
||||
|
||||
private void btnAddProgramSource_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var add = new AddProgramSource(context, _settings);
|
||||
if(add.ShowDialog() ?? false)
|
||||
{
|
||||
ReIndexing();
|
||||
}
|
||||
}
|
||||
|
||||
private void btnDeleteProgramSource_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectedProgramSource = programSourceView.SelectedItem as Settings.ProgramSource;
|
||||
if (selectedProgramSource != null)
|
||||
{
|
||||
string msg = string.Format(context.API.GetTranslation("wox_plugin_program_delete_program_source"), selectedProgramSource.Location);
|
||||
|
||||
if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
|
||||
{
|
||||
_settings.ProgramSources.Remove(selectedProgramSource);
|
||||
ReIndexing();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string msg = context.API.GetTranslation("wox_plugin_program_pls_select_program_source");
|
||||
MessageBox.Show(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnEditProgramSource_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectedProgramSource = programSourceView.SelectedItem as Settings.ProgramSource;
|
||||
if (selectedProgramSource != null)
|
||||
{
|
||||
var add = new AddProgramSource(selectedProgramSource, _settings);
|
||||
if (add.ShowDialog() ?? false)
|
||||
{
|
||||
ReIndexing();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string msg = context.API.GetTranslation("wox_plugin_program_pls_select_program_source");
|
||||
MessageBox.Show(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnReindex_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ReIndexing();
|
||||
}
|
||||
|
||||
private void BtnProgramSuffixes_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var p = new ProgramSuffixes(context, _settings);
|
||||
if (p.ShowDialog() ?? false)
|
||||
{
|
||||
ReIndexing();
|
||||
}
|
||||
}
|
||||
|
||||
private void programSourceView_DragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
{
|
||||
e.Effects = DragDropEffects.Link;
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Effects = DragDropEffects.None;
|
||||
}
|
||||
}
|
||||
|
||||
private void programSourceView_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
|
||||
|
||||
if (files != null && files.Length > 0)
|
||||
{
|
||||
foreach (string s in files)
|
||||
{
|
||||
if (Directory.Exists(s))
|
||||
{
|
||||
_settings.ProgramSources.Add(new Settings.ProgramSource
|
||||
{
|
||||
Location = s
|
||||
});
|
||||
|
||||
ReIndexing();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void StartMenuEnabled_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_settings.EnableStartMenuSource = StartMenuEnabled.IsChecked ?? false;
|
||||
ReIndexing();
|
||||
}
|
||||
|
||||
private void RegistryEnabled_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_settings.EnableRegistrySource = RegistryEnabled.IsChecked ?? false;
|
||||
ReIndexing();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wox.Plugin.Program.Programs
|
||||
{
|
||||
@ -10,5 +6,8 @@ namespace Wox.Plugin.Program.Programs
|
||||
{
|
||||
List<Result> ContextMenus(IPublicAPI api);
|
||||
Result Result(string query, IPublicAPI api);
|
||||
string UniqueIdentifier { get; set; }
|
||||
string Name { get; }
|
||||
string Location { get; }
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,13 @@ namespace Wox.Plugin.Program.Programs
|
||||
}
|
||||
return u.Apps;
|
||||
}).ToArray();
|
||||
return applications;
|
||||
|
||||
var updatedListWithoutDisabledApps = applications
|
||||
.Where(t1 => !Main._settings.DisabledProgramSources
|
||||
.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
|
||||
.Select(x => x);
|
||||
|
||||
return updatedListWithoutDisabledApps.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -229,11 +235,17 @@ namespace Wox.Plugin.Program.Programs
|
||||
public class Application : IProgram
|
||||
{
|
||||
public string AppListEntry { get; set; }
|
||||
public string UniqueIdentifier { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string UserModelId { get; set; }
|
||||
public string BackgroundColor { get; set; }
|
||||
|
||||
public string Name => DisplayName;
|
||||
public string Location => Package.Location;
|
||||
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
public string LogoUri { get; set; }
|
||||
public string LogoPath { get; set; }
|
||||
public UWP Package { get; set; }
|
||||
@ -321,6 +333,7 @@ namespace Wox.Plugin.Program.Programs
|
||||
public Application(IAppxManifestApplication manifestApp, UWP package)
|
||||
{
|
||||
UserModelId = manifestApp.GetAppUserModelId();
|
||||
UniqueIdentifier = manifestApp.GetAppUserModelId();
|
||||
DisplayName = manifestApp.GetStringValue("DisplayName");
|
||||
Description = manifestApp.GetStringValue("Description");
|
||||
BackgroundColor = manifestApp.GetStringValue("BackgroundColor");
|
||||
@ -330,6 +343,8 @@ namespace Wox.Plugin.Program.Programs
|
||||
Description = ResourceFromPri(package.FullName, Description);
|
||||
LogoUri = LogoUriFromManifest(manifestApp);
|
||||
LogoPath = LogoPathFromUri(LogoUri);
|
||||
|
||||
Enabled = true;
|
||||
}
|
||||
|
||||
internal string ResourceFromPri(string packageFullName, string resourceReference)
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
@ -18,12 +18,15 @@ namespace Wox.Plugin.Program.Programs
|
||||
public class Win32 : IProgram
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string UniqueIdentifier { get; set; }
|
||||
public string IcoPath { get; set; }
|
||||
public string FullPath { get; set; }
|
||||
public string ParentDirectory { get; set; }
|
||||
public string ExecutableName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool Valid { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public string Location => ParentDirectory;
|
||||
|
||||
private const string ShortcutExtension = "lnk";
|
||||
private const string ApplicationReferenceExtension = "appref-ms";
|
||||
@ -127,9 +130,11 @@ namespace Wox.Plugin.Program.Programs
|
||||
Name = Path.GetFileNameWithoutExtension(path),
|
||||
IcoPath = path,
|
||||
FullPath = path,
|
||||
UniqueIdentifier = path,
|
||||
ParentDirectory = Directory.GetParent(path).FullName,
|
||||
Description = string.Empty,
|
||||
Valid = true
|
||||
Valid = true,
|
||||
Enabled = true
|
||||
};
|
||||
return p;
|
||||
}
|
||||
@ -262,9 +267,16 @@ namespace Wox.Plugin.Program.Programs
|
||||
|
||||
private static ParallelQuery<Win32> UnregisteredPrograms(List<Settings.ProgramSource> sources, string[] suffixes)
|
||||
{
|
||||
var paths = sources.Where(s => Directory.Exists(s.Location))
|
||||
.SelectMany(s => ProgramPaths(s.Location, suffixes))
|
||||
.ToArray();
|
||||
var listToAdd = new List<string>();
|
||||
sources.Where(s => Directory.Exists(s.Location) && s.Enabled)
|
||||
.SelectMany(s => ProgramPaths(s.Location, suffixes))
|
||||
.ToList()
|
||||
.Where(t1 => !Main._settings.DisabledProgramSources.Any(x => t1 == x.UniqueIdentifier))
|
||||
.ToList()
|
||||
.ForEach(x => listToAdd.Add(x));
|
||||
|
||||
var paths = listToAdd.Distinct().ToArray();
|
||||
|
||||
var programs1 = paths.AsParallel().Where(p => Extension(p) == ExeExtension).Select(ExeProgram);
|
||||
var programs2 = paths.AsParallel().Where(p => Extension(p) == ShortcutExtension).Select(ExeProgram);
|
||||
var programs3 = from p in paths.AsParallel()
|
||||
@ -276,18 +288,26 @@ namespace Wox.Plugin.Program.Programs
|
||||
|
||||
private static ParallelQuery<Win32> StartMenuPrograms(string[] suffixes)
|
||||
{
|
||||
var disabledProgramsList = Main._settings.DisabledProgramSources;
|
||||
|
||||
var directory1 = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
|
||||
var directory2 = Environment.GetFolderPath(Environment.SpecialFolder.CommonPrograms);
|
||||
var paths1 = ProgramPaths(directory1, suffixes);
|
||||
var paths2 = ProgramPaths(directory2, suffixes);
|
||||
var paths = paths1.Concat(paths2).ToArray();
|
||||
|
||||
var toFilter = paths1.Concat(paths2);
|
||||
var paths = toFilter
|
||||
.Where(t1 => !disabledProgramsList.Any(x => x.UniqueIdentifier == t1))
|
||||
.Select(t1 => t1)
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
var programs1 = paths.AsParallel().Where(p => Extension(p) == ShortcutExtension).Select(LnkProgram);
|
||||
var programs2 = paths.AsParallel().Where(p => Extension(p) == ApplicationReferenceExtension).Select(Win32Program);
|
||||
var programs = programs1.Concat(programs2).Where(p => p.Valid);
|
||||
return programs;
|
||||
}
|
||||
|
||||
|
||||
private static ParallelQuery<Win32> AppPathsPrograms(string[] suffixes)
|
||||
{
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ee872121
|
||||
@ -297,106 +317,88 @@ namespace Wox.Plugin.Program.Programs
|
||||
{
|
||||
if (root != null)
|
||||
{
|
||||
programs.AddRange(ProgramsFromRegistryKey(root));
|
||||
programs.AddRange(GetProgramsFromRegistry(root));
|
||||
}
|
||||
}
|
||||
using (var root = Registry.CurrentUser.OpenSubKey(appPaths))
|
||||
{
|
||||
if (root != null)
|
||||
{
|
||||
programs.AddRange(ProgramsFromRegistryKey(root));
|
||||
programs.AddRange(GetProgramsFromRegistry(root));
|
||||
}
|
||||
}
|
||||
var filtered = programs.AsParallel().Where(p => suffixes.Contains(Extension(p.ExecutableName)));
|
||||
|
||||
var disabledProgramsList = Main._settings.DisabledProgramSources;
|
||||
var toFilter = programs.AsParallel().Where(p => suffixes.Contains(Extension(p.ExecutableName)));
|
||||
|
||||
var filtered = toFilter.Where(t1 => !disabledProgramsList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier)).Select(t1 => t1);
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private static IEnumerable<Win32> ProgramsFromRegistryKey(RegistryKey root)
|
||||
private static IEnumerable<Win32> GetProgramsFromRegistry(RegistryKey root)
|
||||
{
|
||||
var programs = root.GetSubKeyNames()
|
||||
.Select(subkey => ProgramFromRegistrySubkey(root, subkey))
|
||||
.Where(p => !string.IsNullOrEmpty(p.Name));
|
||||
return programs;
|
||||
return root
|
||||
.GetSubKeyNames()
|
||||
.Select(x => GetProgramPathFromRegistrySubKeys(root, x))
|
||||
.Distinct()
|
||||
.Select(x => GetProgramFromPath(x));
|
||||
}
|
||||
|
||||
private static Win32 ProgramFromRegistrySubkey(RegistryKey root, string subkey)
|
||||
private static string GetProgramPathFromRegistrySubKeys(RegistryKey root, string subkey)
|
||||
{
|
||||
var path = string.Empty;
|
||||
|
||||
using (var key = root.OpenSubKey(subkey))
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
var defaultValue = string.Empty;
|
||||
var path = key.GetValue(defaultValue) as string;
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
// fix path like this: ""\"C:\\folder\\executable.exe\""
|
||||
path = path.Trim('"', ' ');
|
||||
path = Environment.ExpandEnvironmentVariables(path);
|
||||
if (key == null)
|
||||
return string.Empty;
|
||||
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var entry = Win32Program(path);
|
||||
entry.ExecutableName = subkey;
|
||||
return entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Win32();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Win32();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Win32();
|
||||
}
|
||||
var defaultValue = string.Empty;
|
||||
path = key.GetValue(defaultValue) as string;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return string.Empty;
|
||||
|
||||
// fix path like this: ""\"C:\\folder\\executable.exe\""
|
||||
return path = path.Trim('"', ' ');
|
||||
}
|
||||
|
||||
//private static Win32 ScoreFilter(Win32 p)
|
||||
//{
|
||||
// var start = new[] { "启动", "start" };
|
||||
// var doc = new[] { "帮助", "help", "文档", "documentation" };
|
||||
// var uninstall = new[] { "卸载", "uninstall" };
|
||||
private static Win32 GetProgramFromPath(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return new Win32();
|
||||
|
||||
// var contained = start.Any(s => p.Name.ToLower().Contains(s));
|
||||
// if (contained)
|
||||
// {
|
||||
// p.Score += 10;
|
||||
// }
|
||||
// contained = doc.Any(d => p.Name.ToLower().Contains(d));
|
||||
// if (contained)
|
||||
// {
|
||||
// p.Score -= 10;
|
||||
// }
|
||||
// contained = uninstall.Any(u => p.Name.ToLower().Contains(u));
|
||||
// if (contained)
|
||||
// {
|
||||
// p.Score -= 20;
|
||||
// }
|
||||
path = Environment.ExpandEnvironmentVariables(path);
|
||||
|
||||
// return p;
|
||||
//}
|
||||
if (!File.Exists(path))
|
||||
return new Win32();
|
||||
|
||||
var entry = Win32Program(path);
|
||||
entry.ExecutableName = Path.GetFileName(path);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
public static Win32[] All(Settings settings)
|
||||
{
|
||||
ParallelQuery<Win32> programs = new List<Win32>().AsParallel();
|
||||
var programs = new List<Win32>().AsParallel();
|
||||
|
||||
var unregistered = UnregisteredPrograms(settings.ProgramSources, settings.ProgramSuffixes);
|
||||
programs = programs.Concat(unregistered);
|
||||
if (settings.EnableRegistrySource)
|
||||
{
|
||||
var appPaths = AppPathsPrograms(settings.ProgramSuffixes);
|
||||
programs = programs.Concat(appPaths);
|
||||
}
|
||||
|
||||
if (settings.EnableStartMenuSource)
|
||||
{
|
||||
var startMenu = StartMenuPrograms(settings.ProgramSuffixes);
|
||||
programs = programs.Concat(startMenu);
|
||||
}
|
||||
var unregistered = UnregisteredPrograms(settings.ProgramSources, settings.ProgramSuffixes);
|
||||
programs = programs.Concat(unregistered);
|
||||
//.Select(ScoreFilter);
|
||||
|
||||
return programs.ToArray();
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using Wox.Plugin.Program.Programs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Wox.Plugin.Program
|
||||
{
|
||||
public class Settings
|
||||
{
|
||||
public DateTime LastIndexTime { get; set; }
|
||||
public List<ProgramSource> ProgramSources { get; set; } = new List<ProgramSource>();
|
||||
public List<DisabledProgramSource> DisabledProgramSources { get; set; } = new List<DisabledProgramSource>();
|
||||
public string[] ProgramSuffixes { get; set; } = {"bat", "appref-ms", "exe", "lnk"};
|
||||
|
||||
public bool EnableStartMenuSource { get; set; } = true;
|
||||
@ -14,9 +17,24 @@ namespace Wox.Plugin.Program
|
||||
|
||||
internal const char SuffixSeperator = ';';
|
||||
|
||||
/// <summary>
|
||||
/// Contains user added folder location contents as well as all user disabled applications
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Win32 class applications set UniqueIdentifier using their full file path</para>
|
||||
/// <para>UWP class applications set UniqueIdentifier using their Application User Model ID</para>
|
||||
/// <para>Custom user added program sources set UniqueIdentifier using their location</para>
|
||||
/// </remarks>
|
||||
public class ProgramSource
|
||||
{
|
||||
private string name;
|
||||
|
||||
public string Location { get; set; }
|
||||
public string Name { get => name ?? new DirectoryInfo(Location).Name; set => name = value; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
public string UniqueIdentifier { get; set; }
|
||||
}
|
||||
|
||||
public class DisabledProgramSource : ProgramSource { }
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Wox.Plugin.Program.Views.Models;
|
||||
|
||||
namespace Wox.Plugin.Program.Views.Commands
|
||||
{
|
||||
internal static class ProgramSettingDisplay
|
||||
{
|
||||
internal static List<ProgramSource> LoadProgramSources(this List<Settings.ProgramSource> programSources)
|
||||
{
|
||||
var list = new List<ProgramSource>();
|
||||
|
||||
programSources.ForEach(x => list
|
||||
.Add(
|
||||
new ProgramSource
|
||||
{
|
||||
Enabled = x.Enabled,
|
||||
Location = x.Location,
|
||||
Name = x.Name,
|
||||
UniqueIdentifier = x.UniqueIdentifier
|
||||
}
|
||||
));
|
||||
|
||||
// Even though these are disabled, we still want to display them so users can enable later on
|
||||
Main._settings
|
||||
.DisabledProgramSources
|
||||
.Where(t1 => !Main._settings
|
||||
.ProgramSources // program sourcces added above already, so exlcude
|
||||
.Any(x => t1.UniqueIdentifier == x.UniqueIdentifier))
|
||||
.Select(x => x)
|
||||
.ToList()
|
||||
.ForEach(x => list
|
||||
.Add(
|
||||
new ProgramSource
|
||||
{
|
||||
Enabled = x.Enabled,
|
||||
Location = x.Location,
|
||||
Name = x.Name,
|
||||
UniqueIdentifier = x.UniqueIdentifier
|
||||
}
|
||||
));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
internal static void LoadAllApplications(this List<ProgramSource> list)
|
||||
{
|
||||
Main._win32s
|
||||
.Where(t1 => !ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
|
||||
.ToList()
|
||||
.ForEach(t1 => ProgramSetting.ProgramSettingDisplayList
|
||||
.Add(
|
||||
new ProgramSource
|
||||
{
|
||||
Name = t1.Name,
|
||||
Location = t1.ParentDirectory,
|
||||
UniqueIdentifier = t1.UniqueIdentifier,
|
||||
Enabled = t1.Enabled
|
||||
}
|
||||
));
|
||||
|
||||
Main._uwps
|
||||
.Where(t1 => !ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
|
||||
.ToList()
|
||||
.ForEach(t1 => ProgramSetting.ProgramSettingDisplayList
|
||||
.Add(
|
||||
new ProgramSource
|
||||
{
|
||||
Name = t1.DisplayName,
|
||||
Location = t1.Package.Location,
|
||||
UniqueIdentifier = t1.UniqueIdentifier,
|
||||
Enabled = t1.Enabled
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
internal static void SetProgramSourcesStatus(this List<ProgramSource> list, List<ProgramSource> selectedProgramSourcesToDisable, bool status)
|
||||
{
|
||||
ProgramSetting.ProgramSettingDisplayList
|
||||
.Where(t1 => selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier && t1.Enabled != status))
|
||||
.ToList()
|
||||
.ForEach(t1 => t1.Enabled = status);
|
||||
|
||||
Main._win32s
|
||||
.Where(t1 => selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier && t1.Enabled != status))
|
||||
.ToList()
|
||||
.ForEach(t1 => t1.Enabled = status);
|
||||
|
||||
Main._uwps
|
||||
.Where(t1 => selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier && t1.Enabled != status))
|
||||
.ToList()
|
||||
.ForEach(t1 => t1.Enabled = status);
|
||||
}
|
||||
|
||||
internal static void StoreDisabledInSettings(this List<ProgramSource> list)
|
||||
{
|
||||
Main._settings.ProgramSources
|
||||
.Where(t1 => ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier && !x.Enabled))
|
||||
.ToList()
|
||||
.ForEach(t1 => t1.Enabled = false);
|
||||
|
||||
ProgramSetting.ProgramSettingDisplayList
|
||||
.Where(t1 => !t1.Enabled
|
||||
&& !Main._settings.DisabledProgramSources.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
|
||||
.ToList()
|
||||
.ForEach(x => Main._settings.DisabledProgramSources
|
||||
.Add(
|
||||
new Settings.DisabledProgramSource
|
||||
{
|
||||
Name = x.Name,
|
||||
Location = x.Location,
|
||||
UniqueIdentifier = x.UniqueIdentifier,
|
||||
Enabled = false
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
internal static void RemoveDisabledFromSettings(this List<ProgramSource> list)
|
||||
{
|
||||
Main._settings.ProgramSources
|
||||
.Where(t1 => ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier && x.Enabled))
|
||||
.ToList()
|
||||
.ForEach(t1 => t1.Enabled = true);
|
||||
|
||||
Main._settings.DisabledProgramSources
|
||||
.Where(t1 => ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier && x.Enabled))
|
||||
.ToList()
|
||||
.ForEach(x => Main._settings.DisabledProgramSources.Remove(x));
|
||||
}
|
||||
|
||||
internal static bool IsReindexRequired(this List<ProgramSource> selectedItems)
|
||||
{
|
||||
if (selectedItems.Where(t1 => t1.Enabled && !Main._uwps.Any(x => t1.UniqueIdentifier == x.UniqueIdentifier)).Count() > 0
|
||||
&& selectedItems.Where(t1 => t1.Enabled && !Main._win32s.Any(x => t1.UniqueIdentifier == x.UniqueIdentifier)).Count() > 0)
|
||||
return true;
|
||||
|
||||
// ProgramSources holds list of user added directories,
|
||||
// so when we enable/disable we need to reindex to show/not show the programs
|
||||
// that are found in those directories.
|
||||
if (selectedItems.Where(t1 => Main._settings.ProgramSources.Any(x => t1.UniqueIdentifier == x.UniqueIdentifier)).Count() > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
5
Plugins/Wox.Plugin.Program/Views/Models/ProgramSource.cs
Normal file
5
Plugins/Wox.Plugin.Program/Views/Models/ProgramSource.cs
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
namespace Wox.Plugin.Program.Views.Models
|
||||
{
|
||||
public class ProgramSource : Settings.ProgramSource { }
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<UserControl x:Class="Wox.Plugin.Program.ProgramSetting"
|
||||
<UserControl x:Class="Wox.Plugin.Program.Views.ProgramSetting"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
@ -13,18 +13,41 @@
|
||||
<RowDefinition Height="50"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<StackPanel Orientation="Vertical" Width="310">
|
||||
<StackPanel Orientation="Vertical" Width="205">
|
||||
<CheckBox Name="StartMenuEnabled" Click="StartMenuEnabled_Click" Margin="5" Content="{DynamicResource wox_plugin_program_index_start}" />
|
||||
<CheckBox Name="RegistryEnabled" Click="RegistryEnabled_Click" Margin="5" Content="{DynamicResource wox_plugin_program_index_registry}" />
|
||||
</StackPanel>
|
||||
<Button Height="30" HorizontalAlignment="Right" x:Name="btnProgramSuffixes" Width="130" Click="BtnProgramSuffixes_OnClick" Content="{DynamicResource wox_plugin_program_suffixes}" />
|
||||
<Button Height="30" HorizontalAlignment="Right" Margin="10 0 0 0" x:Name="btnReindex" Width="100" Click="btnReindex_Click" Content="{DynamicResource wox_plugin_program_reindex}" />
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Button Height="30" HorizontalAlignment="Right" Margin="10" Width="100" x:Name="btnLoadAllProgramSource" Click="btnLoadAllProgramSource_OnClick" Content="{DynamicResource wox_plugin_program_all_programs}" />
|
||||
<Button Height="30" HorizontalAlignment="Right" Margin="10" Width="100" x:Name="btnProgramSuffixes" Click="BtnProgramSuffixes_OnClick" Content="{DynamicResource wox_plugin_program_suffixes}" />
|
||||
<Button Height="30" HorizontalAlignment="Right" Margin="10" Width="100" x:Name="btnReindex" Click="btnReindex_Click" Content="{DynamicResource wox_plugin_program_reindex}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<ListView x:Name="programSourceView" Grid.Row="1" AllowDrop="True"
|
||||
<ListView x:Name="programSourceView" Grid.Row="1" AllowDrop="True" SelectionMode="Extended" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler"
|
||||
PreviewMouseRightButtonUp="ProgramSourceView_PreviewMouseRightButtonUp"
|
||||
DragEnter="programSourceView_DragEnter"
|
||||
Drop="programSourceView_Drop" >
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<EventSetter Event="PreviewMouseUp" Handler="Row_OnClick"/>
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="Name" Width="150">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Name}"/>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Header="Enabled" Width="50">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Enabled}"/>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Header="{DynamicResource wox_plugin_program_location}" Width="550">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
@ -41,9 +64,9 @@
|
||||
<TextBlock Margin="10 0 0 0" Height="20" HorizontalAlignment="Center" Text="{DynamicResource wox_plugin_program_indexing}" />
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Button x:Name="btnDeleteProgramSource" Click="btnDeleteProgramSource_OnClick" Width="100" Margin="10" Content="{DynamicResource wox_plugin_program_delete}"/>
|
||||
<Button x:Name="btnEditProgramSource" Click="btnEditProgramSource_OnClick" Width="100" Margin="10" Content="{DynamicResource wox_plugin_program_edit}"/>
|
||||
<Button x:Name="btnProgramSourceStatus" Click="btnProgramSourceStatus_OnClick" Width="100" Margin="10" Content="{DynamicResource wox_plugin_program_disable}" />
|
||||
<Button x:Name="btnAddProgramSource" Click="btnAddProgramSource_OnClick" Width="100" Margin="10" Content="{DynamicResource wox_plugin_program_add}"/>
|
||||
<Button x:Name="btnEditProgramSource" Click="btnEditProgramSource_OnClick" Width="100" Margin="10" Content="{DynamicResource wox_plugin_program_edit}"/>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</Grid>
|
307
Plugins/Wox.Plugin.Program/Views/ProgramSetting.xaml.cs
Normal file
307
Plugins/Wox.Plugin.Program/Views/ProgramSetting.xaml.cs
Normal file
@ -0,0 +1,307 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using Wox.Plugin.Program.Views.Models;
|
||||
using Wox.Plugin.Program.Views.Commands;
|
||||
using Wox.Plugin.Program.Programs;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Wox.Plugin.Program.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ProgramSetting.xaml
|
||||
/// </summary>
|
||||
public partial class ProgramSetting : UserControl
|
||||
{
|
||||
private PluginInitContext context;
|
||||
private Settings _settings;
|
||||
private GridViewColumnHeader _lastHeaderClicked;
|
||||
private ListSortDirection _lastDirection;
|
||||
|
||||
// We do not save all program sources to settings, so using
|
||||
// this as temporary holder for displaying all loaded programs sources.
|
||||
internal static List<ProgramSource> ProgramSettingDisplayList { get; set; }
|
||||
|
||||
public ProgramSetting(PluginInitContext context, Settings settings, Win32[] win32s, UWP.Application[] uwps)
|
||||
{
|
||||
this.context = context;
|
||||
InitializeComponent();
|
||||
Loaded += Setting_Loaded;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
private void Setting_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ProgramSettingDisplayList = _settings.ProgramSources.LoadProgramSources();
|
||||
programSourceView.ItemsSource = ProgramSettingDisplayList;
|
||||
|
||||
StartMenuEnabled.IsChecked = _settings.EnableStartMenuSource;
|
||||
RegistryEnabled.IsChecked = _settings.EnableRegistrySource;
|
||||
}
|
||||
|
||||
private void ReIndexing()
|
||||
{
|
||||
programSourceView.Items.Refresh();
|
||||
Task.Run(() =>
|
||||
{
|
||||
Dispatcher.Invoke(() => { indexingPanel.Visibility = Visibility.Visible; });
|
||||
Main.IndexPrograms();
|
||||
Dispatcher.Invoke(() => { indexingPanel.Visibility = Visibility.Hidden; });
|
||||
});
|
||||
}
|
||||
|
||||
private void btnAddProgramSource_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var add = new AddProgramSource(context, _settings);
|
||||
if(add.ShowDialog() ?? false)
|
||||
{
|
||||
ReIndexing();
|
||||
}
|
||||
|
||||
programSourceView.Items.Refresh();
|
||||
}
|
||||
|
||||
private void DeleteProgramSources(List<ProgramSource> itemsToDelete)
|
||||
{
|
||||
itemsToDelete.ForEach(t1 => _settings.ProgramSources
|
||||
.Remove(_settings.ProgramSources
|
||||
.Where(x => x.UniqueIdentifier == t1.UniqueIdentifier)
|
||||
.FirstOrDefault()));
|
||||
itemsToDelete.ForEach(x => ProgramSettingDisplayList.Remove(x));
|
||||
|
||||
ReIndexing();
|
||||
}
|
||||
|
||||
private void btnEditProgramSource_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectedProgramSource = programSourceView.SelectedItem as Settings.ProgramSource;
|
||||
if (selectedProgramSource != null)
|
||||
{
|
||||
var add = new AddProgramSource(selectedProgramSource, _settings);
|
||||
if (add.ShowDialog() ?? false)
|
||||
{
|
||||
ReIndexing();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string msg = context.API.GetTranslation("wox_plugin_program_pls_select_program_source");
|
||||
MessageBox.Show(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnReindex_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ReIndexing();
|
||||
}
|
||||
|
||||
private void BtnProgramSuffixes_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var p = new ProgramSuffixes(context, _settings);
|
||||
if (p.ShowDialog() ?? false)
|
||||
{
|
||||
ReIndexing();
|
||||
}
|
||||
}
|
||||
|
||||
private void programSourceView_DragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
{
|
||||
e.Effects = DragDropEffects.Link;
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Effects = DragDropEffects.None;
|
||||
}
|
||||
}
|
||||
|
||||
private void programSourceView_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
var directories = (string[])e.Data.GetData(DataFormats.FileDrop);
|
||||
|
||||
var directoriesToAdd = new List<ProgramSource>();
|
||||
|
||||
if (directories != null && directories.Length > 0)
|
||||
{
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
if (Directory.Exists(directory) && !ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == directory))
|
||||
{
|
||||
var source = new ProgramSource
|
||||
{
|
||||
Location = directory,
|
||||
UniqueIdentifier = directory
|
||||
};
|
||||
|
||||
directoriesToAdd.Add(source);
|
||||
}
|
||||
}
|
||||
|
||||
if (directoriesToAdd.Count() > 0)
|
||||
{
|
||||
directoriesToAdd.ForEach(x => _settings.ProgramSources.Add(x));
|
||||
directoriesToAdd.ForEach(x => ProgramSettingDisplayList.Add(x));
|
||||
|
||||
programSourceView.Items.Refresh();
|
||||
ReIndexing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void StartMenuEnabled_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_settings.EnableStartMenuSource = StartMenuEnabled.IsChecked ?? false;
|
||||
ReIndexing();
|
||||
}
|
||||
|
||||
private void RegistryEnabled_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_settings.EnableRegistrySource = RegistryEnabled.IsChecked ?? false;
|
||||
ReIndexing();
|
||||
}
|
||||
|
||||
private void btnLoadAllProgramSource_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ProgramSettingDisplayList.LoadAllApplications();
|
||||
|
||||
programSourceView.Items.Refresh();
|
||||
}
|
||||
|
||||
private void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectedItems = programSourceView
|
||||
.SelectedItems.Cast<ProgramSource>()
|
||||
.ToList();
|
||||
|
||||
if (selectedItems.Count() == 0)
|
||||
{
|
||||
string msg = context.API.GetTranslation("wox_plugin_program_pls_select_program_source");
|
||||
MessageBox.Show(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedItems
|
||||
.Where(t1 => !_settings
|
||||
.ProgramSources
|
||||
.Any(x => t1.UniqueIdentifier == x.UniqueIdentifier))
|
||||
.Count() == 0)
|
||||
{
|
||||
var msg = string.Format(context.API.GetTranslation("wox_plugin_program_delete_program_source"));
|
||||
|
||||
if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DeleteProgramSources(selectedItems);
|
||||
}
|
||||
else if (IsSelectedRowStatusEnabledMoreOrEqualThanDisabled(selectedItems))
|
||||
{
|
||||
ProgramSettingDisplayList.SetProgramSourcesStatus(selectedItems, false);
|
||||
|
||||
ProgramSettingDisplayList.StoreDisabledInSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgramSettingDisplayList.SetProgramSourcesStatus(selectedItems, true);
|
||||
|
||||
ProgramSettingDisplayList.RemoveDisabledFromSettings();
|
||||
}
|
||||
|
||||
if (selectedItems.IsReindexRequired())
|
||||
ReIndexing();
|
||||
|
||||
programSourceView.SelectedItems.Clear();
|
||||
|
||||
programSourceView.Items.Refresh();
|
||||
}
|
||||
|
||||
private void ProgramSourceView_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
programSourceView.SelectedItems.Clear();
|
||||
}
|
||||
|
||||
private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var headerClicked = e.OriginalSource as GridViewColumnHeader;
|
||||
ListSortDirection direction;
|
||||
|
||||
if (headerClicked != null)
|
||||
{
|
||||
if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
|
||||
{
|
||||
if (headerClicked != _lastHeaderClicked)
|
||||
{
|
||||
direction = ListSortDirection.Ascending;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_lastDirection == ListSortDirection.Ascending)
|
||||
{
|
||||
direction = ListSortDirection.Descending;
|
||||
}
|
||||
else
|
||||
{
|
||||
direction = ListSortDirection.Ascending;
|
||||
}
|
||||
}
|
||||
|
||||
var columnBinding = headerClicked.Column.DisplayMemberBinding as Binding;
|
||||
var sortBy = columnBinding?.Path.Path ?? headerClicked.Column.Header as string;
|
||||
|
||||
Sort(sortBy, direction);
|
||||
|
||||
_lastHeaderClicked = headerClicked;
|
||||
_lastDirection = direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Sort(string sortBy, ListSortDirection direction)
|
||||
{
|
||||
var dataView = CollectionViewSource.GetDefaultView(programSourceView.ItemsSource);
|
||||
|
||||
dataView.SortDescriptions.Clear();
|
||||
SortDescription sd = new SortDescription(sortBy, direction);
|
||||
dataView.SortDescriptions.Add(sd);
|
||||
dataView.Refresh();
|
||||
}
|
||||
|
||||
private bool IsSelectedRowStatusEnabledMoreOrEqualThanDisabled(List<ProgramSource> selectedItems)
|
||||
{
|
||||
return selectedItems.Where(x => x.Enabled).Count() >= selectedItems.Where(x => !x.Enabled).Count();
|
||||
}
|
||||
|
||||
private void Row_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectedItems = programSourceView
|
||||
.SelectedItems.Cast<ProgramSource>()
|
||||
.ToList();
|
||||
|
||||
if (selectedItems
|
||||
.Where(t1 => !_settings
|
||||
.ProgramSources
|
||||
.Any(x => t1.UniqueIdentifier == x.UniqueIdentifier))
|
||||
.Count() == 0)
|
||||
{
|
||||
btnProgramSourceStatus.Content = context.API.GetTranslation("wox_plugin_program_delete");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsSelectedRowStatusEnabledMoreOrEqualThanDisabled(selectedItems))
|
||||
{
|
||||
btnProgramSourceStatus.Content = "Disable";
|
||||
}
|
||||
else
|
||||
{
|
||||
btnProgramSourceStatus.Content = "Enable";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -71,13 +71,15 @@
|
||||
<Compile Include="AddProgramSource.xaml.cs">
|
||||
<DependentUpon>AddProgramSource.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\Commands\ProgramSettingDisplay.cs" />
|
||||
<Compile Include="FileChangeWatcher.cs" />
|
||||
<Compile Include="Views\Models\ProgramSource.cs" />
|
||||
<Compile Include="Programs\IProgram.cs" />
|
||||
<Compile Include="Programs\UWP.cs" />
|
||||
<Compile Include="Programs\Win32.cs" />
|
||||
<Compile Include="SuffixesConverter.cs" />
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="ProgramSetting.xaml.cs">
|
||||
<Compile Include="Views\ProgramSetting.xaml.cs">
|
||||
<DependentUpon>ProgramSetting.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Settings.cs" />
|
||||
@ -103,6 +105,9 @@
|
||||
<None Include="Images\folder.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Images\disable.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Include="Languages\en.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
@ -135,7 +140,7 @@
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Page Include="ProgramSetting.xaml">
|
||||
<Page Include="Views\ProgramSetting.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
|
Loading…
Reference in New Issue
Block a user