2022-08-08 21:55:04 +00:00
|
|
|
|
using System;
|
2013-12-20 11:38:10 +00:00
|
|
|
|
using System.Collections.Generic;
|
2014-07-16 10:52:00 +00:00
|
|
|
|
using System.IO;
|
2022-04-12 09:30:04 +00:00
|
|
|
|
using System.Threading.Tasks;
|
2022-09-13 22:34:11 +00:00
|
|
|
|
using System.Windows.Controls;
|
2016-08-18 00:16:40 +00:00
|
|
|
|
using System.Windows.Media;
|
2013-12-19 15:51:20 +00:00
|
|
|
|
|
2020-04-21 09:12:17 +00:00
|
|
|
|
namespace Flow.Launcher.Plugin
|
2014-10-23 10:39:11 +00:00
|
|
|
|
{
|
2022-08-08 21:55:04 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Describes the result of a plugin
|
|
|
|
|
|
/// </summary>
|
2014-10-23 10:39:11 +00:00
|
|
|
|
public class Result
|
|
|
|
|
|
{
|
2016-05-05 15:08:44 +00:00
|
|
|
|
|
2016-05-03 20:18:26 +00:00
|
|
|
|
private string _pluginDirectory;
|
2021-12-29 19:39:39 +00:00
|
|
|
|
|
2016-05-03 20:18:26 +00:00
|
|
|
|
private string _icoPath;
|
2021-04-15 04:06:53 +00:00
|
|
|
|
|
2021-04-15 04:09:01 +00:00
|
|
|
|
/// <summary>
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// The title of the result. This is always required.
|
2021-04-15 04:09:01 +00:00
|
|
|
|
/// </summary>
|
2014-10-23 10:39:11 +00:00
|
|
|
|
public string Title { get; set; }
|
2021-04-15 04:06:53 +00:00
|
|
|
|
|
2021-04-15 04:09:01 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Provides additional details for the result. This is optional
|
|
|
|
|
|
/// </summary>
|
2021-04-15 04:06:53 +00:00
|
|
|
|
public string SubTitle { get; set; } = string.Empty;
|
2014-10-23 10:39:11 +00:00
|
|
|
|
|
2020-03-31 11:00:09 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// This holds the action keyword that triggered the result.
|
|
|
|
|
|
/// If result is triggered by global keyword: *, this should be empty.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string ActionKeywordAssigned { get; set; }
|
|
|
|
|
|
|
2022-01-27 05:35:45 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// This holds the text which can be provided by plugin to be copied to the
|
|
|
|
|
|
/// user's clipboard when Ctrl + C is pressed on a result. If the text is a file/directory path
|
|
|
|
|
|
/// flow will copy the actual file/folder instead of just the path text.
|
|
|
|
|
|
/// </summary>
|
2022-10-23 22:04:25 +00:00
|
|
|
|
public string CopyText
|
|
|
|
|
|
{
|
|
|
|
|
|
get => string.IsNullOrEmpty(_copyText) ? SubTitle : _copyText;
|
|
|
|
|
|
set => _copyText = value;
|
|
|
|
|
|
}
|
2021-12-04 05:48:18 +00:00
|
|
|
|
|
2021-12-05 07:40:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// This holds the text which can be provided by plugin to help Flow autocomplete text
|
|
|
|
|
|
/// for user on the plugin result. If autocomplete action for example is tab, pressing tab will have
|
|
|
|
|
|
/// the default constructed autocomplete text (result's Title), or the text provided here if not empty.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string AutoCompleteText { get; set; }
|
2021-12-03 10:44:33 +00:00
|
|
|
|
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Image Displayed on the result
|
2021-12-30 21:56:28 +00:00
|
|
|
|
/// <value>Relative Path to the Image File</value>
|
2021-12-30 21:56:13 +00:00
|
|
|
|
/// <remarks>GlyphInfo is prioritized if not null</remarks>
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// </summary>
|
2016-08-18 00:16:40 +00:00
|
|
|
|
public string IcoPath
|
2014-10-23 10:39:11 +00:00
|
|
|
|
{
|
2016-05-03 20:18:26 +00:00
|
|
|
|
get { return _icoPath; }
|
|
|
|
|
|
set
|
2014-10-23 10:39:11 +00:00
|
|
|
|
{
|
2022-11-24 06:31:00 +00:00
|
|
|
|
// As a standard this property will handle prepping and converting to absolute local path for icon image processing
|
|
|
|
|
|
if (!string.IsNullOrEmpty(value)
|
|
|
|
|
|
&& !string.IsNullOrEmpty(PluginDirectory)
|
|
|
|
|
|
&& !Path.IsPathRooted(value)
|
|
|
|
|
|
&& !value.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
|
&& !value.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
2014-10-23 10:39:11 +00:00
|
|
|
|
{
|
2022-11-24 06:31:00 +00:00
|
|
|
|
_icoPath = Path.Combine(PluginDirectory, value);
|
2016-05-03 20:18:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_icoPath = value;
|
2014-10-23 10:39:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-08-30 08:26:22 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Determines if Icon has a border radius
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool RoundedIcon { get; set; } = false;
|
2014-10-23 10:39:11 +00:00
|
|
|
|
|
2022-08-08 21:55:04 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Delegate function, see <see cref="Icon"/>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
2016-08-18 00:16:40 +00:00
|
|
|
|
public delegate ImageSource IconDelegate();
|
|
|
|
|
|
|
2021-07-31 07:44:41 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Delegate to Get Image Source
|
|
|
|
|
|
/// </summary>
|
2021-11-29 07:08:55 +00:00
|
|
|
|
public IconDelegate Icon;
|
2022-10-23 22:04:25 +00:00
|
|
|
|
private string _copyText = string.Empty;
|
2021-07-31 07:44:41 +00:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// Information for Glyph Icon (Prioritized than IcoPath/Icon if user enable Glyph Icons)
|
2021-07-31 07:44:41 +00:00
|
|
|
|
/// </summary>
|
2021-12-29 19:39:39 +00:00
|
|
|
|
public GlyphInfo Glyph { get; init; }
|
2016-08-18 00:16:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
2014-10-23 10:39:11 +00:00
|
|
|
|
/// <summary>
|
2021-12-31 16:59:53 +00:00
|
|
|
|
/// Delegate. An action to take in the form of a function call when the result has been selected
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// <returns>
|
|
|
|
|
|
/// true to hide flowlauncher after select result
|
|
|
|
|
|
/// </returns>
|
2014-10-23 10:39:11 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Func<ActionContext, bool> Action { get; set; }
|
|
|
|
|
|
|
2022-04-12 09:30:04 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Delegate. An Async action to take in the form of a function call when the result has been selected
|
|
|
|
|
|
/// <returns>
|
|
|
|
|
|
/// true to hide flowlauncher after select result
|
|
|
|
|
|
/// </returns>
|
|
|
|
|
|
/// </summary>
|
2022-04-15 23:32:05 +00:00
|
|
|
|
public Func<ActionContext, ValueTask<bool>> AsyncAction { get; set; }
|
2022-04-12 09:30:04 +00:00
|
|
|
|
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Priority of the current result
|
2021-12-29 19:45:22 +00:00
|
|
|
|
/// <value>default: 0</value>
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// </summary>
|
2014-10-23 10:39:11 +00:00
|
|
|
|
public int Score { get; set; }
|
|
|
|
|
|
|
2019-12-03 14:10:21 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// A list of indexes for the characters to be highlighted in Title
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public IList<int> TitleHighlightData { get; set; }
|
|
|
|
|
|
|
2022-08-08 21:55:04 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Deprecated as of Flow Launcher v1.9.1. Subtitle highlighting is no longer offered
|
|
|
|
|
|
/// </summary>
|
2021-12-20 20:19:31 +00:00
|
|
|
|
[Obsolete("Deprecated as of Flow Launcher v1.9.1. Subtitle highlighting is no longer offered")]
|
2019-12-03 14:10:21 +00:00
|
|
|
|
public IList<int> SubTitleHighlightData { get; set; }
|
|
|
|
|
|
|
2014-10-23 10:39:11 +00:00
|
|
|
|
/// <summary>
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// Query information associated with the result
|
2014-10-23 10:39:11 +00:00
|
|
|
|
/// </summary>
|
2020-03-03 22:25:59 +00:00
|
|
|
|
internal Query OriginQuery { get; set; }
|
2014-10-23 10:39:11 +00:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2015-01-24 14:34:55 +00:00
|
|
|
|
/// Plugin directory
|
2014-10-23 10:39:11 +00:00
|
|
|
|
/// </summary>
|
2016-05-03 20:18:26 +00:00
|
|
|
|
public string PluginDirectory
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _pluginDirectory; }
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
_pluginDirectory = value;
|
2022-11-24 06:31:00 +00:00
|
|
|
|
|
|
|
|
|
|
// When the Result object is returned from the query call, PluginDirectory is not provided until
|
|
|
|
|
|
// UpdatePluginMetadata call is made at PluginManager.cs L196. Once the PluginDirectory becomes available
|
|
|
|
|
|
// we need to update (only if not Uri path) the IcoPath with the full absolute path so the image can be loaded.
|
|
|
|
|
|
IcoPath = _icoPath;
|
2016-05-03 20:18:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-10-23 10:39:11 +00:00
|
|
|
|
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// <inheritdoc />
|
2015-11-06 21:30:38 +00:00
|
|
|
|
public override bool Equals(object obj)
|
2014-10-23 10:39:11 +00:00
|
|
|
|
{
|
2019-08-31 06:58:15 +00:00
|
|
|
|
var r = obj as Result;
|
|
|
|
|
|
|
|
|
|
|
|
var equality = string.Equals(r?.Title, Title) &&
|
|
|
|
|
|
string.Equals(r?.SubTitle, SubTitle) &&
|
2019-12-03 14:10:21 +00:00
|
|
|
|
string.Equals(r?.IcoPath, IcoPath) &&
|
2021-12-20 20:19:31 +00:00
|
|
|
|
TitleHighlightData == r.TitleHighlightData;
|
2019-08-31 06:58:15 +00:00
|
|
|
|
|
|
|
|
|
|
return equality;
|
2015-11-06 21:30:38 +00:00
|
|
|
|
}
|
2014-10-23 10:39:11 +00:00
|
|
|
|
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// <inheritdoc />
|
2015-11-06 21:30:38 +00:00
|
|
|
|
public override int GetHashCode()
|
|
|
|
|
|
{
|
2015-11-11 06:20:52 +00:00
|
|
|
|
var hashcode = (Title?.GetHashCode() ?? 0) ^
|
2016-04-27 01:15:53 +00:00
|
|
|
|
(SubTitle?.GetHashCode() ?? 0);
|
2015-11-09 03:20:02 +00:00
|
|
|
|
return hashcode;
|
2014-10-23 10:39:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// <inheritdoc />
|
2014-10-23 10:39:11 +00:00
|
|
|
|
public override string ToString()
|
|
|
|
|
|
{
|
|
|
|
|
|
return Title + SubTitle;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-02-04 15:16:41 +00:00
|
|
|
|
/// <summary>
|
2021-12-30 17:35:09 +00:00
|
|
|
|
/// Additional data associated with this result
|
2021-12-29 19:39:39 +00:00
|
|
|
|
/// <example>
|
|
|
|
|
|
/// As external information for ContextMenu
|
|
|
|
|
|
/// </example>
|
2015-02-04 15:16:41 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public object ContextData { get; set; }
|
|
|
|
|
|
|
2015-01-24 14:34:55 +00:00
|
|
|
|
/// <summary>
|
2019-12-03 21:02:24 +00:00
|
|
|
|
/// Plugin ID that generated this result
|
2015-01-24 14:34:55 +00:00
|
|
|
|
/// </summary>
|
2020-03-03 22:25:59 +00:00
|
|
|
|
public string PluginID { get; internal set; }
|
2020-06-29 20:45:04 +00:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Show message as ToolTip on result Title hover over
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string TitleToolTip { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Show message as ToolTip on result SubTitle hover over
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string SubTitleToolTip { get; set; }
|
2022-08-08 21:55:04 +00:00
|
|
|
|
|
2022-09-13 22:34:11 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Customized Preview Panel
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Lazy<UserControl> PreviewPanel { get; set; }
|
|
|
|
|
|
|
2022-08-08 21:55:04 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Run this result, asynchronously
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="context"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2022-04-12 09:30:04 +00:00
|
|
|
|
public ValueTask<bool> ExecuteAsync(ActionContext context)
|
|
|
|
|
|
{
|
2022-04-15 23:32:05 +00:00
|
|
|
|
return AsyncAction?.Invoke(context) ?? ValueTask.FromResult(Action?.Invoke(context) ?? false);
|
2022-04-12 09:30:04 +00:00
|
|
|
|
}
|
2022-09-06 14:59:33 +00:00
|
|
|
|
|
2022-09-11 22:05:03 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Progress bar display. Providing an int value between 0-100 will trigger the progress bar to be displayed on the result
|
|
|
|
|
|
/// </summary>
|
2022-09-06 14:59:33 +00:00
|
|
|
|
public int? ProgressBar { get; set; }
|
2022-09-11 22:05:03 +00:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Optionally set the color of the progress bar
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <default>#26a0da (blue)</default>
|
|
|
|
|
|
public string ProgressBarColor { get; set; } = "#26a0da";
|
2022-11-29 04:59:13 +00:00
|
|
|
|
|
2022-12-05 08:01:20 +00:00
|
|
|
|
public PreviewInfo Preview { get; set; } = PreviewInfo.Default;
|
|
|
|
|
|
|
2022-11-29 04:59:13 +00:00
|
|
|
|
/// <summary>
|
2022-12-05 08:01:20 +00:00
|
|
|
|
/// Info of the preview image.
|
2022-11-29 04:59:13 +00:00
|
|
|
|
/// </summary>
|
2022-12-05 08:01:20 +00:00
|
|
|
|
public record PreviewInfo
|
2022-11-29 04:59:13 +00:00
|
|
|
|
{
|
2022-12-05 08:01:20 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Full image used for preview panel
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string PreviewImagePath { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Determines if the preview image should occupy the full width of the preveiw panel.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool IsMedia { get; set; }
|
|
|
|
|
|
public string Description { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public static PreviewInfo Default { get; } = new()
|
|
|
|
|
|
{
|
|
|
|
|
|
PreviewImagePath = null,
|
|
|
|
|
|
Description = null,
|
|
|
|
|
|
IsMedia = false,
|
|
|
|
|
|
};
|
2022-11-29 04:59:13 +00:00
|
|
|
|
}
|
2014-10-23 10:39:11 +00:00
|
|
|
|
}
|
2022-08-08 21:55:04 +00:00
|
|
|
|
}
|