mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-11-23 19:49:17 +08:00
Cleanup
This commit is contained in:
parent
50153b0cce
commit
75a31da666
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
|
||||
using AdvancedPaste.Telemetry;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
|
||||
|
@ -7,6 +7,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ManagedCommon;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.Storage.Streams;
|
||||
|
@ -93,7 +93,8 @@ internal static class DataPackageHelpers
|
||||
return availableFormats == ClipboardFormat.Text ? !string.IsNullOrEmpty(await dataPackageView.GetTextAsync()) : availableFormats != ClipboardFormat.None;
|
||||
}
|
||||
|
||||
internal static async Task<string> GetTextOrEmptyAsync(this DataPackageView dataPackageView) => dataPackageView.Contains(StandardDataFormats.Text) ? await dataPackageView.GetTextAsync() : string.Empty;
|
||||
internal static async Task<string> GetTextOrEmptyAsync(this DataPackageView dataPackageView) =>
|
||||
dataPackageView.Contains(StandardDataFormats.Text) ? await dataPackageView.GetTextAsync() : string.Empty;
|
||||
|
||||
internal static async Task<string> GetTextOrHtmlTextAsync(this DataPackageView dataPackageView)
|
||||
{
|
||||
|
@ -33,30 +33,23 @@ namespace AdvancedPaste.Helpers
|
||||
private static readonly Regex CsvRemoveStartAndEndQuotationMarksRegex = new Regex(@"^""(?=(""{2})+)|(?<=(""{2})+)""$");
|
||||
private static readonly Regex CsvReplaceDoubleQuotationMarksRegex = new Regex(@"""{2}");
|
||||
|
||||
internal static string ToJsonFromXmlOrCsv(DataPackageView clipboardData)
|
||||
internal static async Task<string> ToJsonFromXmlOrCsvAsync(DataPackageView clipboardData)
|
||||
{
|
||||
Logger.LogTrace();
|
||||
|
||||
if (clipboardData == null || !clipboardData.Contains(StandardDataFormats.Text))
|
||||
if (!clipboardData.Contains(StandardDataFormats.Text))
|
||||
{
|
||||
Logger.LogWarning("Clipboard does not contain text data");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
|
||||
string text = Task.Run(async () =>
|
||||
{
|
||||
string plainText = await clipboardData.GetTextAsync() as string;
|
||||
return plainText;
|
||||
}).Result;
|
||||
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
|
||||
|
||||
var text = await clipboardData.GetTextAsync();
|
||||
string jsonText = string.Empty;
|
||||
|
||||
// Try convert XML
|
||||
try
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
XmlDocument doc = new();
|
||||
doc.LoadXml(text);
|
||||
Logger.LogDebug("Converted from XML.");
|
||||
jsonText = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented);
|
||||
|
@ -15,67 +15,15 @@ namespace AdvancedPaste.Helpers
|
||||
{
|
||||
internal static class MarkdownHelper
|
||||
{
|
||||
public static string ToMarkdown(DataPackageView clipboardData)
|
||||
public static async Task<string> ToMarkdownAsync(DataPackageView clipboardData)
|
||||
{
|
||||
Logger.LogTrace();
|
||||
|
||||
if (clipboardData == null)
|
||||
{
|
||||
Logger.LogWarning("Clipboard does not contain data");
|
||||
var data = clipboardData.Contains(StandardDataFormats.Html) ? await clipboardData.GetHtmlFormatAsync()
|
||||
: clipboardData.Contains(StandardDataFormats.Text) ? await clipboardData.GetTextAsync()
|
||||
: string.Empty;
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string data = string.Empty;
|
||||
|
||||
if (clipboardData.Contains(StandardDataFormats.Html))
|
||||
{
|
||||
data = Task.Run(async () =>
|
||||
{
|
||||
string data = await clipboardData.GetHtmlFormatAsync() as string;
|
||||
return data;
|
||||
}).Result;
|
||||
}
|
||||
else if (clipboardData.Contains(StandardDataFormats.Text))
|
||||
{
|
||||
data = Task.Run(async () =>
|
||||
{
|
||||
string plainText = await clipboardData.GetTextAsync() as string;
|
||||
return plainText;
|
||||
}).Result;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(data))
|
||||
{
|
||||
string cleanedHtml = CleanHtml(data);
|
||||
|
||||
return ConvertHtmlToMarkdown(cleanedHtml);
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static string PasteAsPlainTextFromClipboard(DataPackageView clipboardData)
|
||||
{
|
||||
Logger.LogTrace();
|
||||
|
||||
if (clipboardData != null)
|
||||
{
|
||||
if (!clipboardData.Contains(StandardDataFormats.Text))
|
||||
{
|
||||
Logger.LogWarning("Clipboard does not contain text data");
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
string plainText = await clipboardData.GetTextAsync() as string;
|
||||
return plainText;
|
||||
}).Result;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
return string.IsNullOrEmpty(data) ? string.Empty : ConvertHtmlToMarkdown(CleanHtml(data));
|
||||
}
|
||||
|
||||
private static string CleanHtml(string html)
|
||||
|
@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Windows.Globalization;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.Media.Ocr;
|
||||
|
@ -21,9 +21,9 @@ public static class TransformHelpers
|
||||
{
|
||||
return format switch
|
||||
{
|
||||
PasteFormats.PlainText => ToPlainText(clipboardData),
|
||||
PasteFormats.Markdown => ToMarkdown(clipboardData),
|
||||
PasteFormats.Json => ToJson(clipboardData),
|
||||
PasteFormats.PlainText => await ToPlainTextAsync(clipboardData),
|
||||
PasteFormats.Markdown => await ToMarkdownAsync(clipboardData),
|
||||
PasteFormats.Json => await ToJsonAsync(clipboardData),
|
||||
PasteFormats.ImageToText => await ImageToTextAsync(clipboardData),
|
||||
PasteFormats.PasteAsTxtFile => await ToTxtFileAsync(clipboardData),
|
||||
PasteFormats.PasteAsPngFile => await ToPngFileAsync(clipboardData),
|
||||
@ -34,22 +34,22 @@ public static class TransformHelpers
|
||||
};
|
||||
}
|
||||
|
||||
private static DataPackage ToPlainText(DataPackageView clipboardData)
|
||||
private static async Task<DataPackage> ToPlainTextAsync(DataPackageView clipboardData)
|
||||
{
|
||||
Logger.LogTrace();
|
||||
return CreateDataPackageFromText(MarkdownHelper.PasteAsPlainTextFromClipboard(clipboardData));
|
||||
return CreateDataPackageFromText(await clipboardData.GetTextOrEmptyAsync());
|
||||
}
|
||||
|
||||
private static DataPackage ToMarkdown(DataPackageView clipboardData)
|
||||
private static async Task<DataPackage> ToMarkdownAsync(DataPackageView clipboardData)
|
||||
{
|
||||
Logger.LogTrace();
|
||||
return CreateDataPackageFromText(MarkdownHelper.ToMarkdown(clipboardData));
|
||||
return CreateDataPackageFromText(await MarkdownHelper.ToMarkdownAsync(clipboardData));
|
||||
}
|
||||
|
||||
private static DataPackage ToJson(DataPackageView clipboardData)
|
||||
private static async Task<DataPackage> ToJsonAsync(DataPackageView clipboardData)
|
||||
{
|
||||
Logger.LogTrace();
|
||||
return CreateDataPackageFromText(JsonHelper.ToJsonFromXmlOrCsv(clipboardData));
|
||||
return CreateDataPackageFromText(await JsonHelper.ToJsonFromXmlOrCsvAsync(clipboardData));
|
||||
}
|
||||
|
||||
private static async Task<DataPackage> ImageToTextAsync(DataPackageView clipboardData)
|
||||
|
@ -14,5 +14,5 @@ public enum ClipboardFormat
|
||||
Html = 1 << 1,
|
||||
Audio = 1 << 2,
|
||||
Image = 1 << 3,
|
||||
File = 1 << 4,
|
||||
File = 1 << 4, // output only for now
|
||||
}
|
||||
|
@ -62,5 +62,8 @@ public sealed class PasteFormat
|
||||
|
||||
public string ShortcutText { get; set; } = string.Empty;
|
||||
|
||||
public bool SupportsClipboardFormats(ClipboardFormat clipboardFormats) => (clipboardFormats & Metadata.SupportedClipboardFormats) != ClipboardFormat.None;
|
||||
public static bool SupportsClipboardFormats(PasteFormats format, ClipboardFormat clipboardFormats)
|
||||
=> (clipboardFormats & MetadataDict[format].SupportedClipboardFormats) != ClipboardFormat.None;
|
||||
|
||||
public bool SupportsClipboardFormats(ClipboardFormat clipboardFormats) => SupportsClipboardFormats(Format, clipboardFormats);
|
||||
}
|
||||
|
@ -14,7 +14,8 @@ public enum PasteFormats
|
||||
IconGlyph = "\uE8E9",
|
||||
RequiresAIService = false,
|
||||
CanPreview = false,
|
||||
SupportedClipboardFormats = ClipboardFormat.Text)]
|
||||
SupportedClipboardFormats = ClipboardFormat.Text,
|
||||
KernelFunctionDescription = "Takes clipboard text and returns it as it is.")]
|
||||
PlainText,
|
||||
|
||||
[PasteFormatMetadata(
|
||||
|
@ -18,6 +18,11 @@ using Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
namespace AdvancedPaste.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Implements <see cref="IKernelQueryCacheService"/> by only caching queries with prompts
|
||||
/// that correspond to the user's custom actions or to the localized names of bundled actions.
|
||||
/// This avoids potential privacy issues and prevents the cache from getting too large.
|
||||
/// </summary>
|
||||
public sealed class CustomActionKernelQueryCacheService : IKernelQueryCacheService
|
||||
{
|
||||
private const string PersistedCacheFileName = "kernelQueryCache.json";
|
||||
@ -39,7 +44,7 @@ public sealed class CustomActionKernelQueryCacheService : IKernelQueryCacheServi
|
||||
|
||||
_userSettings.Changed += OnUserSettingsChanged;
|
||||
|
||||
RefreshCacheablePrompts();
|
||||
UpdateCacheablePrompts();
|
||||
|
||||
_memoryCache = LoadPersistedCacheItems().Where(pair => pair.CacheKey != null)
|
||||
.GroupBy(pair => pair.CacheKey, pair => pair.CacheValue)
|
||||
@ -92,7 +97,7 @@ public sealed class CustomActionKernelQueryCacheService : IKernelQueryCacheServi
|
||||
|
||||
private async void OnUserSettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
RefreshCacheablePrompts();
|
||||
UpdateCacheablePrompts();
|
||||
|
||||
if (RemoveInapplicableCacheKeys())
|
||||
{
|
||||
@ -100,7 +105,7 @@ public sealed class CustomActionKernelQueryCacheService : IKernelQueryCacheServi
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshCacheablePrompts()
|
||||
private void UpdateCacheablePrompts()
|
||||
{
|
||||
var localizedActionNames = from pair in PasteFormat.MetadataDict
|
||||
let format = pair.Key
|
||||
@ -112,7 +117,6 @@ public sealed class CustomActionKernelQueryCacheService : IKernelQueryCacheServi
|
||||
var customActionPrompts = from customAction in _userSettings.CustomActions
|
||||
select customAction.Prompt;
|
||||
|
||||
// Only cache queries with these prompts to prevent the cache from getting too large and to avoid potential privacy issues.
|
||||
_cacheablePrompts.Clear();
|
||||
_cacheablePrompts.UnionWith(localizedActionNames.Concat(customActionPrompts));
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
|
||||
namespace AdvancedPaste.Services;
|
||||
|
@ -30,7 +30,7 @@ public sealed class PasteFormatExecutor(IKernelService kernelService, ICustomTex
|
||||
|
||||
var clipboardData = Clipboard.GetContent();
|
||||
|
||||
// Run on thread-pool; even though we use Async routines consistently, some actions still occasionally take a long time without yielding.
|
||||
// Run on thread-pool; although we use Async routines consistently, some actions still occasionally take a long time without yielding.
|
||||
return await Task.Run(async () =>
|
||||
pasteFormat.Format switch
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ namespace AdvancedPaste.ViewModels
|
||||
|
||||
public bool ClipboardHasData => AvailableClipboardFormats != ClipboardFormat.None;
|
||||
|
||||
public bool ClipboardHasDataForCustomAI => (AvailableClipboardFormats & PasteFormat.MetadataDict[CustomAIFormat].SupportedClipboardFormats) != ClipboardFormat.None;
|
||||
public bool ClipboardHasDataForCustomAI => PasteFormat.SupportsClipboardFormats(CustomAIFormat, AvailableClipboardFormats);
|
||||
|
||||
private PasteFormats CustomAIFormat => _userSettings.IsAdvancedAIEnabled ? PasteFormats.KernelQuery : PasteFormats.CustomTextTransformation;
|
||||
|
||||
@ -166,7 +166,7 @@ namespace AdvancedPaste.ViewModels
|
||||
private PasteFormat CreateStandardPasteFormat(PasteFormats format) =>
|
||||
PasteFormat.CreateStandardFormat(format, AvailableClipboardFormats, IsCustomAIServiceEnabled, ResourceLoaderInstance.ResourceLoader.GetString);
|
||||
|
||||
private PasteFormat CreateAIServiceFormat(string name, string prompt, bool isSavedQuery) =>
|
||||
private PasteFormat CreateCustomAIPasteFormat(string name, string prompt, bool isSavedQuery) =>
|
||||
PasteFormat.CreateCustomAIFormat(CustomAIFormat, name, prompt, isSavedQuery, AvailableClipboardFormats, IsCustomAIServiceEnabled);
|
||||
|
||||
private void RefreshPasteFormats()
|
||||
@ -208,7 +208,7 @@ namespace AdvancedPaste.ViewModels
|
||||
|
||||
UpdateFormats(
|
||||
CustomActionPasteFormats,
|
||||
IsCustomAIServiceEnabled ? _userSettings.CustomActions.Select(customAction => CreateAIServiceFormat(customAction.Name, customAction.Prompt, isSavedQuery: true)) : []);
|
||||
IsCustomAIServiceEnabled ? _userSettings.CustomActions.Select(customAction => CreateCustomAIPasteFormat(customAction.Name, customAction.Prompt, isSavedQuery: true)) : []);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@ -436,7 +436,7 @@ namespace AdvancedPaste.ViewModels
|
||||
if (customAction != null)
|
||||
{
|
||||
await ReadClipboardAsync();
|
||||
await ExecutePasteFormatAsync(CreateAIServiceFormat(customAction.Name, customAction.Prompt, isSavedQuery: true), source);
|
||||
await ExecutePasteFormatAsync(CreateCustomAIPasteFormat(customAction.Name, customAction.Prompt, isSavedQuery: true), source);
|
||||
}
|
||||
}
|
||||
|
||||
@ -445,7 +445,7 @@ namespace AdvancedPaste.ViewModels
|
||||
var customAction = _userSettings.CustomActions
|
||||
.FirstOrDefault(customAction => Models.KernelQueryCache.CacheKey.PromptComparer.Equals(customAction.Prompt, Query));
|
||||
|
||||
await ExecutePasteFormatAsync(CreateAIServiceFormat(customAction?.Name ?? "Default", Query, isSavedQuery: customAction != null), triggerSource);
|
||||
await ExecutePasteFormatAsync(CreateCustomAIPasteFormat(customAction?.Name ?? "Default", Query, isSavedQuery: customAction != null), triggerSource);
|
||||
}
|
||||
|
||||
private void HideWindow()
|
||||
|
@ -270,9 +270,9 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void parse_hotkeys(PowerToysSettings::PowerToyValues& settings)
|
||||
void read_settings(PowerToysSettings::PowerToyValues& settings)
|
||||
{
|
||||
auto settingsObject = settings.get_raw_json();
|
||||
const auto settingsObject = settings.get_raw_json();
|
||||
|
||||
// Migrate Paste As Plain text shortcut
|
||||
Hotkey old_paste_as_plain_hotkey;
|
||||
@ -354,6 +354,21 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settingsObject.GetView().Size())
|
||||
{
|
||||
const auto propertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES);
|
||||
|
||||
if (propertiesObject.HasKey(JSON_KEY_IS_ADVANCED_AI_ENABLED))
|
||||
{
|
||||
m_is_advanced_ai_enabled = propertiesObject.GetNamedObject(JSON_KEY_IS_ADVANCED_AI_ENABLED).GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
|
||||
if (propertiesObject.HasKey(JSON_KEY_SHOW_CUSTOM_PREVIEW))
|
||||
{
|
||||
m_preview_custom_format_output = propertiesObject.GetNamedObject(JSON_KEY_SHOW_CUSTOM_PREVIEW).GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool is_process_running() const
|
||||
@ -443,23 +458,7 @@ private:
|
||||
PowerToysSettings::PowerToyValues settings =
|
||||
PowerToysSettings::PowerToyValues::load_from_settings_file(get_key());
|
||||
|
||||
parse_hotkeys(settings);
|
||||
|
||||
const auto settingsObject = settings.get_raw_json();
|
||||
if (settingsObject.GetView().Size())
|
||||
{
|
||||
const auto propertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES);
|
||||
|
||||
if (propertiesObject.HasKey(JSON_KEY_IS_ADVANCED_AI_ENABLED))
|
||||
{
|
||||
m_is_advanced_ai_enabled = propertiesObject.GetNamedObject(JSON_KEY_IS_ADVANCED_AI_ENABLED).GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
|
||||
if (propertiesObject.HasKey(JSON_KEY_SHOW_CUSTOM_PREVIEW))
|
||||
{
|
||||
m_preview_custom_format_output = propertiesObject.GetNamedObject(JSON_KEY_SHOW_CUSTOM_PREVIEW).GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
}
|
||||
read_settings(settings);
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
@ -821,23 +820,7 @@ public:
|
||||
PowerToysSettings::PowerToyValues values =
|
||||
PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
|
||||
|
||||
parse_hotkeys(values);
|
||||
|
||||
const auto settingsObject = values.get_raw_json();
|
||||
if (settingsObject.GetView().Size())
|
||||
{
|
||||
const auto propertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES);
|
||||
|
||||
if (propertiesObject.HasKey(JSON_KEY_IS_ADVANCED_AI_ENABLED))
|
||||
{
|
||||
m_is_advanced_ai_enabled = propertiesObject.GetNamedObject(JSON_KEY_IS_ADVANCED_AI_ENABLED).GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
|
||||
if (propertiesObject.HasKey(JSON_KEY_SHOW_CUSTOM_PREVIEW))
|
||||
{
|
||||
m_preview_custom_format_output = propertiesObject.GetNamedObject(JSON_KEY_SHOW_CUSTOM_PREVIEW).GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
}
|
||||
read_settings(values);
|
||||
|
||||
std::unordered_map<std::wstring, Hotkey> additionalActionMap;
|
||||
for (const auto& action : m_additional_actions)
|
||||
|
Loading…
Reference in New Issue
Block a user