mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +01:00
* Progress! * Progress... * POC level. * Added ability to delete from history using IPublicAPI * Some sorting, works in some cases. * Rename "Run History" back to just "History". * Updated item from review. * Slight change to PowerLauncher ref, set Copy Local = False * Fixed missing history items if added to history without search term. * Added placeholder unit test project * Updates for new History plugin. * Update Product.wxs, removed useless Unit Test project * Removed actual files for "Microsoft.PowerToys.Run.Plugin.History.UnitTests" * Added history.md, updated ESRPSigning_core.json * Changes for review * Removed now global CodeAnalysis/stylecop
252 lines
8.8 KiB
C#
252 lines
8.8 KiB
C#
// Copyright (c) Microsoft Corporation
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using ManagedCommon;
|
|
using Microsoft.PowerToys.Run.Plugin.History.Properties;
|
|
using PowerLauncher.Plugin;
|
|
using Wox.Plugin;
|
|
|
|
namespace Microsoft.PowerToys.Run.Plugin.History
|
|
{
|
|
public class Main : IPlugin, IContextMenu, IPluginI18n, IDisposable
|
|
{
|
|
private PluginInitContext Context { get; set; }
|
|
|
|
private string IconPath { get; set; }
|
|
|
|
public string Name => Resources.wox_plugin_history_plugin_name;
|
|
|
|
public string Description => Resources.wox_plugin_history_plugin_description;
|
|
|
|
private bool _disposed;
|
|
|
|
public List<Result> Query(Query query)
|
|
{
|
|
var results = new List<Result>();
|
|
try
|
|
{
|
|
if (query.SelectedItems != null)
|
|
{
|
|
var scoreCounter = 1000;
|
|
|
|
// System.Diagnostics.Debugger.Launch();
|
|
foreach (var historyItem in query.SelectedItems.Values.OrderByDescending(sel => sel.LastSelected))
|
|
{
|
|
if (historyItem.PluginID == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var plugin = PluginManager.AllPlugins.FirstOrDefault(p => p.Metadata.ID == historyItem.PluginID);
|
|
|
|
if (query.Search != string.Empty && !IsRelevant(query, historyItem))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var result = BuildResult(historyItem);
|
|
|
|
if (result != null)
|
|
{
|
|
// very special case for Calculator
|
|
if (plugin.Metadata.Name == "Calculator")
|
|
{
|
|
result.HistoryTitle = result.Title;
|
|
result.Title = $"{historyItem.Search} = {historyItem.Title}";
|
|
}
|
|
|
|
if (query.RawQuery.StartsWith(query.ActionKeyword, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
// this is just the history view, update the scores.
|
|
result.Score = scoreCounter--;
|
|
}
|
|
|
|
results.Add(result);
|
|
}
|
|
else
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("Skipping " + historyItem.Title);
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
// System.Diagnostics.Debugger.Launch();
|
|
bool isGlobalQuery = string.IsNullOrEmpty(query.ActionKeyword);
|
|
return ErrorHandler.OnError(IconPath, isGlobalQuery, query.RawQuery, default, e);
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
private bool IsRelevant(Query query, UserSelectedRecord.UserSelectedRecordItem genericSelectedItem)
|
|
{
|
|
if (genericSelectedItem.Title != null && genericSelectedItem.Title.Contains(query.Search, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
else if (genericSelectedItem.SubTitle != null && genericSelectedItem.SubTitle.Contains(query.Search, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
else if (genericSelectedItem.Search != null && genericSelectedItem.Search.Contains(query.Search, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private Result BuildResult(UserSelectedRecord.UserSelectedRecordItem historyItem)
|
|
{
|
|
Result result = null;
|
|
|
|
var plugin = PluginManager.AllPlugins.FirstOrDefault(x => x.Metadata.ID == historyItem.PluginID);
|
|
|
|
var searchTerm = historyItem.Search;
|
|
if (string.IsNullOrEmpty(searchTerm))
|
|
{
|
|
searchTerm = historyItem.Title;
|
|
}
|
|
|
|
var tempResults = PluginManager.QueryForPlugin(plugin, new Query(searchTerm), false);
|
|
|
|
if (tempResults != null)
|
|
{
|
|
result = tempResults.FirstOrDefault(r => r.Title == historyItem.Title && r.SubTitle == historyItem.SubTitle);
|
|
|
|
if (result == null)
|
|
{
|
|
// do less exact match, some plugins (like shell), have a dynamic SubTitle
|
|
result = tempResults.FirstOrDefault(r => r.Title == historyItem.Title);
|
|
}
|
|
}
|
|
|
|
if (result == null)
|
|
{
|
|
tempResults = PluginManager.QueryForPlugin(plugin, new Query(searchTerm), true);
|
|
if (tempResults != null)
|
|
{
|
|
result = tempResults.FirstOrDefault(r => r.Title == historyItem.Title && r.SubTitle == historyItem.SubTitle);
|
|
|
|
if (result == null)
|
|
{
|
|
// do less exact match, some plugins (like shell), have a dynamic SubTitle
|
|
result = tempResults.FirstOrDefault(r => r.Title == historyItem.Title);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (result != null)
|
|
{
|
|
result.FromHistory = true;
|
|
result.HistoryPluginID = historyItem.PluginID;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public void Init(PluginInitContext context)
|
|
{
|
|
Context = context ?? throw new ArgumentNullException(paramName: nameof(context));
|
|
|
|
Context.API.ThemeChanged += OnThemeChanged;
|
|
UpdateIconPath(Context.API.GetCurrentTheme());
|
|
}
|
|
|
|
private void UpdateIconPath(Theme theme)
|
|
{
|
|
if (theme == Theme.Light || theme == Theme.HighContrastWhite)
|
|
{
|
|
IconPath = "Images/history.light.png";
|
|
}
|
|
else
|
|
{
|
|
IconPath = "Images/history.dark.png";
|
|
}
|
|
}
|
|
|
|
private void OnThemeChanged(Theme currentTheme, Theme newTheme)
|
|
{
|
|
UpdateIconPath(newTheme);
|
|
}
|
|
|
|
public string GetTranslatedPluginTitle()
|
|
{
|
|
return Resources.wox_plugin_history_plugin_name;
|
|
}
|
|
|
|
public string GetTranslatedPluginDescription()
|
|
{
|
|
return Resources.wox_plugin_history_plugin_description;
|
|
}
|
|
|
|
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
|
|
{
|
|
var pluginPair = PluginManager.AllPlugins.FirstOrDefault(x => x.Metadata.ID == selectedResult.HistoryPluginID);
|
|
if (pluginPair != null)
|
|
{
|
|
List<ContextMenuResult> menuItems = new List<ContextMenuResult>();
|
|
if (pluginPair.Plugin.GetType().GetInterface(nameof(IContextMenu)) != null)
|
|
{
|
|
var plugin = (IContextMenu)pluginPair.Plugin;
|
|
menuItems = plugin.LoadContextMenus(selectedResult);
|
|
}
|
|
|
|
menuItems.Add(new ContextMenuResult
|
|
{
|
|
// https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-ui-symbol-font
|
|
FontFamily = "Segoe MDL2 Assets",
|
|
Glyph = "\xF739", // ECC9 => Symbol: RemoveFrom, or F739 => SetHistoryStatus2
|
|
Title = $"Remove this from history",
|
|
Action = _ =>
|
|
{
|
|
// very special case for Calculator
|
|
if (pluginPair.Plugin.Name == "Calculator")
|
|
{
|
|
selectedResult.Title = selectedResult.HistoryTitle;
|
|
}
|
|
|
|
PluginManager.API.RemoveUserSelectedItem(selectedResult);
|
|
|
|
return true;
|
|
},
|
|
});
|
|
|
|
return menuItems;
|
|
}
|
|
|
|
return new List<ContextMenuResult>();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(disposing: true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (!_disposed)
|
|
{
|
|
if (disposing)
|
|
{
|
|
if (Context != null && Context.API != null)
|
|
{
|
|
Context.API.ThemeChanged -= OnThemeChanged;
|
|
}
|
|
|
|
_disposed = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|