mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 09:46:54 +02:00
[AdvancedPaste]Additional actions - Image to text, Paste as file (txt, png, html) (#35167)
* [AdvancedPaste] Additional actions, including Image to text * Spellcheck issue * [AdvancedPaste] Paste as file and many other improvements * Fixed typo * Fixed typo * [AdvancedPaste] Improved paste window menu layout * [AdvancedPaste] Improved settings window layout * [AdvancedPaste] Removed AudioToText for the moment * Code cleanup * Minor fixes * Changed log-line with potentially sensitive info * Extra telemetry for AdvancedPaste * Added 'Hotkey' suffix to AdvancedPaste_Settings telemetry event
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
// 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.Text.Json.Serialization;
|
||||
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
public sealed partial class AdvancedPasteAdditionalAction : Observable, IAdvancedPasteAction
|
||||
{
|
||||
private HotkeySettings _shortcut = new();
|
||||
private bool _isShown = true;
|
||||
|
||||
[JsonPropertyName("shortcut")]
|
||||
public HotkeySettings Shortcut
|
||||
{
|
||||
get => _shortcut;
|
||||
set
|
||||
{
|
||||
if (_shortcut != value)
|
||||
{
|
||||
// We null-coalesce here rather than outside this branch as we want to raise PropertyChanged when the setter is called
|
||||
// with null; the ShortcutControl depends on this.
|
||||
_shortcut = value ?? new();
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("isShown")]
|
||||
public bool IsShown
|
||||
{
|
||||
get => _isShown;
|
||||
set => Set(ref _isShown, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
public sealed class AdvancedPasteAdditionalActions
|
||||
{
|
||||
public static class PropertyNames
|
||||
{
|
||||
public const string ImageToText = "image-to-text";
|
||||
public const string PasteAsFile = "paste-as-file";
|
||||
}
|
||||
|
||||
[JsonPropertyName(PropertyNames.ImageToText)]
|
||||
public AdvancedPasteAdditionalAction ImageToText { get; init; } = new();
|
||||
|
||||
[JsonPropertyName(PropertyNames.PasteAsFile)]
|
||||
public AdvancedPastePasteAsFileAction PasteAsFile { get; init; } = new();
|
||||
|
||||
[JsonIgnore]
|
||||
public IEnumerable<IAdvancedPasteAction> AllActions => new IAdvancedPasteAction[] { ImageToText, PasteAsFile }.Concat(PasteAsFile.SubActions);
|
||||
}
|
||||
@@ -3,14 +3,13 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
public sealed class AdvancedPasteCustomAction : INotifyPropertyChanged, ICloneable
|
||||
public sealed class AdvancedPasteCustomAction : Observable, IAdvancedPasteAction, ICloneable
|
||||
{
|
||||
private int _id;
|
||||
private string _name = string.Empty;
|
||||
@@ -25,14 +24,7 @@ public sealed class AdvancedPasteCustomAction : INotifyPropertyChanged, ICloneab
|
||||
public int Id
|
||||
{
|
||||
get => _id;
|
||||
set
|
||||
{
|
||||
if (_id != value)
|
||||
{
|
||||
_id = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
set => Set(ref _id, value);
|
||||
}
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
@@ -41,10 +33,8 @@ public sealed class AdvancedPasteCustomAction : INotifyPropertyChanged, ICloneab
|
||||
get => _name;
|
||||
set
|
||||
{
|
||||
if (_name != value)
|
||||
if (Set(ref _name, value))
|
||||
{
|
||||
_name = value;
|
||||
OnPropertyChanged();
|
||||
UpdateIsValid();
|
||||
}
|
||||
}
|
||||
@@ -56,10 +46,8 @@ public sealed class AdvancedPasteCustomAction : INotifyPropertyChanged, ICloneab
|
||||
get => _prompt;
|
||||
set
|
||||
{
|
||||
if (_prompt != value)
|
||||
if (Set(ref _prompt, value))
|
||||
{
|
||||
_prompt = value;
|
||||
OnPropertyChanged();
|
||||
UpdateIsValid();
|
||||
}
|
||||
}
|
||||
@@ -86,62 +74,30 @@ public sealed class AdvancedPasteCustomAction : INotifyPropertyChanged, ICloneab
|
||||
public bool IsShown
|
||||
{
|
||||
get => _isShown;
|
||||
set
|
||||
{
|
||||
if (_isShown != value)
|
||||
{
|
||||
_isShown = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
set => Set(ref _isShown, value);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public bool CanMoveUp
|
||||
{
|
||||
get => _canMoveUp;
|
||||
set
|
||||
{
|
||||
if (_canMoveUp != value)
|
||||
{
|
||||
_canMoveUp = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
set => Set(ref _canMoveUp, value);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public bool CanMoveDown
|
||||
{
|
||||
get => _canMoveDown;
|
||||
set
|
||||
{
|
||||
if (_canMoveDown != value)
|
||||
{
|
||||
_canMoveDown = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
set => Set(ref _canMoveDown, value);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public bool IsValid
|
||||
{
|
||||
get => _isValid;
|
||||
private set
|
||||
{
|
||||
if (_isValid != value)
|
||||
{
|
||||
_isValid = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
private set => Set(ref _isValid, value);
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public string ToJsonString() => JsonSerializer.Serialize(this);
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
AdvancedPasteCustomAction clone = new();
|
||||
@@ -160,11 +116,6 @@ public sealed class AdvancedPasteCustomAction : INotifyPropertyChanged, ICloneab
|
||||
CanMoveDown = other.CanMoveDown;
|
||||
}
|
||||
|
||||
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
private HotkeySettings GetShortcutClone()
|
||||
{
|
||||
object shortcut = null;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
public sealed class AdvancedPastePasteAsFileAction : Observable, IAdvancedPasteAction
|
||||
{
|
||||
public static class PropertyNames
|
||||
{
|
||||
public const string PasteAsTxtFile = "paste-as-txt-file";
|
||||
public const string PasteAsPngFile = "paste-as-png-file";
|
||||
public const string PasteAsHtmlFile = "paste-as-html-file";
|
||||
}
|
||||
|
||||
private AdvancedPasteAdditionalAction _pasteAsTxtFile = new();
|
||||
private AdvancedPasteAdditionalAction _pasteAsPngFile = new();
|
||||
private AdvancedPasteAdditionalAction _pasteAsHtmlFile = new();
|
||||
private bool _isShown = true;
|
||||
|
||||
[JsonPropertyName("isShown")]
|
||||
public bool IsShown
|
||||
{
|
||||
get => _isShown;
|
||||
set => Set(ref _isShown, value);
|
||||
}
|
||||
|
||||
[JsonPropertyName(PropertyNames.PasteAsTxtFile)]
|
||||
public AdvancedPasteAdditionalAction PasteAsTxtFile
|
||||
{
|
||||
get => _pasteAsTxtFile;
|
||||
init => Set(ref _pasteAsTxtFile, value);
|
||||
}
|
||||
|
||||
[JsonPropertyName(PropertyNames.PasteAsPngFile)]
|
||||
public AdvancedPasteAdditionalAction PasteAsPngFile
|
||||
{
|
||||
get => _pasteAsPngFile;
|
||||
init => Set(ref _pasteAsPngFile, value);
|
||||
}
|
||||
|
||||
[JsonPropertyName(PropertyNames.PasteAsHtmlFile)]
|
||||
public AdvancedPasteAdditionalAction PasteAsHtmlFile
|
||||
{
|
||||
get => _pasteAsHtmlFile;
|
||||
init => Set(ref _pasteAsHtmlFile, value);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public IEnumerable<AdvancedPasteAdditionalAction> SubActions => [PasteAsTxtFile, PasteAsPngFile, PasteAsHtmlFile];
|
||||
}
|
||||
@@ -22,6 +22,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
PasteAsMarkdownShortcut = new();
|
||||
PasteAsJsonShortcut = new();
|
||||
CustomActions = new();
|
||||
AdditionalActions = new();
|
||||
ShowCustomPreview = true;
|
||||
SendPasteKeyCombination = true;
|
||||
CloseAfterLosingFocus = false;
|
||||
@@ -51,7 +52,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
[JsonPropertyName("custom-actions")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public AdvancedPasteCustomActions CustomActions { get; set; }
|
||||
public AdvancedPasteCustomActions CustomActions { get; init; }
|
||||
|
||||
[JsonPropertyName("additional-actions")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public AdvancedPasteAdditionalActions AdditionalActions { get; init; }
|
||||
|
||||
public override string ToString()
|
||||
=> JsonSerializer.Serialize(this);
|
||||
|
||||
@@ -11,17 +11,19 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Helpers
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
||||
protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (Equals(storage, value))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
storage = value;
|
||||
OnPropertyChanged(propertyName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
12
src/settings-ui/Settings.UI.Library/IAdvancedPasteAction.cs
Normal file
12
src/settings-ui/Settings.UI.Library/IAdvancedPasteAction.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
// 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.ComponentModel;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
public interface IAdvancedPasteAction : INotifyPropertyChanged
|
||||
{
|
||||
public bool IsShown { get; }
|
||||
}
|
||||
@@ -24,6 +24,18 @@
|
||||
<ImageSource x:Key="DialogHeaderImage">ms-appx:///Assets/Settings/Modules/APDialog.light.png</ImageSource>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
<DataTemplate x:Key="AdditionalActionTemplate" x:DataType="models:AdvancedPasteAdditionalAction">
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<controls:ShortcutControl
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
AllowDisable="True"
|
||||
HotkeySettings="{x:Bind Shortcut, Mode=TwoWay}" />
|
||||
<ToggleSwitch
|
||||
IsOn="{x:Bind IsShown, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
OffContent=""
|
||||
OnContent="" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
<Grid>
|
||||
@@ -129,6 +141,7 @@
|
||||
AllowDisable="True"
|
||||
HotkeySettings="{x:Bind Path=ViewModel.PasteAsJsonShortcut, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
|
||||
<ItemsControl
|
||||
x:Name="CustomActions"
|
||||
x:Uid="CustomActions"
|
||||
@@ -155,7 +168,7 @@
|
||||
HotkeySettings="{x:Bind Path=Shortcut, Mode=TwoWay}" />
|
||||
<ToggleSwitch
|
||||
x:Uid="Enable_CustomAction"
|
||||
AutomationProperties.HelpText="{x:Bind Name}"
|
||||
AutomationProperties.HelpText="{x:Bind Name, Mode=OneWay}"
|
||||
IsOn="{x:Bind IsShown, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
OffContent=""
|
||||
OnContent="" />
|
||||
@@ -202,6 +215,56 @@
|
||||
IsTabStop="{x:Bind ViewModel.IsConflictingCopyShortcut, Mode=OneWay}"
|
||||
Severity="Warning" />
|
||||
</controls:SettingsGroup>
|
||||
|
||||
<controls:SettingsGroup x:Uid="AdvancedPaste_Additional_Actions_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard x:Uid="ImageToText" DataContext="{x:Bind ViewModel.AdditionalActions.ImageToText, Mode=OneWay}">
|
||||
<ContentControl ContentTemplate="{StaticResource AdditionalActionTemplate}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
|
||||
<tkcontrols:SettingsExpander
|
||||
x:Uid="PasteAsFile"
|
||||
DataContext="{x:Bind ViewModel.AdditionalActions.PasteAsFile, Mode=OneWay}"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsExpanded="{Binding IsShown, Mode=OneWay}">
|
||||
<tkcontrols:SettingsExpander.Content>
|
||||
<ToggleSwitch
|
||||
IsOn="{Binding IsShown, Mode=TwoWay}"
|
||||
OffContent=""
|
||||
OnContent="" />
|
||||
</tkcontrols:SettingsExpander.Content>
|
||||
<tkcontrols:SettingsExpander.Items>
|
||||
<!-- HACK: For some weird reason, a ShortcutControl does not work correctly if it's the first or last item in the expander, so we add an invisible card. -->
|
||||
<tkcontrols:SettingsCard Visibility="Collapsed" />
|
||||
<tkcontrols:SettingsCard
|
||||
x:Uid="PasteAsTxtFile"
|
||||
DataContext="{Binding PasteAsTxtFile, Mode=TwoWay}"
|
||||
IsEnabled="{x:Bind ViewModel.AdditionalActions.PasteAsFile.IsShown, Mode=OneWay}">
|
||||
<ContentControl ContentTemplate="{StaticResource AdditionalActionTemplate}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard
|
||||
x:Uid="PasteAsPngFile"
|
||||
DataContext="{Binding PasteAsPngFile, Mode=TwoWay}"
|
||||
IsEnabled="{x:Bind ViewModel.AdditionalActions.PasteAsFile.IsShown, Mode=OneWay}">
|
||||
<ContentControl ContentTemplate="{StaticResource AdditionalActionTemplate}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard
|
||||
x:Uid="PasteAsHtmlFile"
|
||||
DataContext="{Binding PasteAsHtmlFile, Mode=TwoWay}"
|
||||
IsEnabled="{x:Bind ViewModel.AdditionalActions.PasteAsFile.IsShown, Mode=OneWay}">
|
||||
<ContentControl ContentTemplate="{StaticResource AdditionalActionTemplate}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<!-- HACK: For some weird reason, a ShortcutControl does not work correctly if it's the first or last item in the expander, so we add an invisible card. -->
|
||||
<tkcontrols:SettingsCard Visibility="Collapsed" />
|
||||
</tkcontrols:SettingsExpander.Items>
|
||||
</tkcontrols:SettingsExpander>
|
||||
|
||||
<InfoBar
|
||||
x:Uid="AdvancedPaste_ShortcutWarning"
|
||||
IsClosable="False"
|
||||
IsOpen="{x:Bind ViewModel.IsAdditionalActionConflictingCopyShortcut, Mode=OneWay}"
|
||||
IsTabStop="{x:Bind ViewModel.IsAdditionalActionConflictingCopyShortcut, Mode=OneWay}"
|
||||
Severity="Warning" />
|
||||
</controls:SettingsGroup>
|
||||
</StackPanel>
|
||||
</controls:SettingsPageControl.ModuleContent>
|
||||
<controls:SettingsPageControl.PrimaryLinks>
|
||||
|
||||
@@ -725,6 +725,9 @@
|
||||
<data name="AdvancedPaste_Direct_Access_Hotkeys_GroupSettings.Header" xml:space="preserve">
|
||||
<value>Actions</value>
|
||||
</data>
|
||||
<data name="AdvancedPaste_Additional_Actions_GroupSettings.Header" xml:space="preserve">
|
||||
<value>Additional actions</value>
|
||||
</data>
|
||||
<data name="RemapKeysList.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Current Key Remappings</value>
|
||||
</data>
|
||||
@@ -2046,6 +2049,21 @@ Made with 💗 by Microsoft and the PowerToys community.</value>
|
||||
<data name="PasteAsCustom_Shortcut.Header" xml:space="preserve">
|
||||
<value>Paste as Custom with AI directly</value>
|
||||
</data>
|
||||
<data name="ImageToText.Header" xml:space="preserve">
|
||||
<value>Image to text</value>
|
||||
</data>
|
||||
<data name="PasteAsFile.Header" xml:space="preserve">
|
||||
<value>Paste as file</value>
|
||||
</data>
|
||||
<data name="PasteAsTxtFile.Header" xml:space="preserve">
|
||||
<value>Paste as .txt file</value>
|
||||
</data>
|
||||
<data name="PasteAsPngFile.Header" xml:space="preserve">
|
||||
<value>Paste as .png file</value>
|
||||
</data>
|
||||
<data name="PasteAsHtmlFile.Header" xml:space="preserve">
|
||||
<value>Paste as .html file</value>
|
||||
</data>
|
||||
<data name="AdvancedPaste_EnableAIDialogOpenAIApiKey.Text" xml:space="preserve">
|
||||
<value>OpenAI API key:</value>
|
||||
</data>
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
private readonly object _delayedActionLock = new object();
|
||||
|
||||
private readonly AdvancedPasteSettings _advancedPasteSettings;
|
||||
private readonly AdvancedPasteAdditionalActions _additionalActions;
|
||||
private readonly ObservableCollection<AdvancedPasteCustomAction> _customActions;
|
||||
private Timer _delayedTimer;
|
||||
|
||||
@@ -69,6 +70,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
_advancedPasteSettings = advancedPasteSettingsRepository.SettingsConfig;
|
||||
|
||||
_additionalActions = _advancedPasteSettings.Properties.AdditionalActions;
|
||||
_customActions = _advancedPasteSettings.Properties.CustomActions.Value;
|
||||
|
||||
InitializeEnabledValue();
|
||||
@@ -81,6 +83,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
_delayedTimer.Elapsed += DelayedTimer_Tick;
|
||||
_delayedTimer.AutoReset = false;
|
||||
|
||||
foreach (var action in _additionalActions.AllActions)
|
||||
{
|
||||
action.PropertyChanged += OnAdditionalActionPropertyChanged;
|
||||
}
|
||||
|
||||
foreach (var customAction in _customActions)
|
||||
{
|
||||
customAction.PropertyChanged += OnCustomActionPropertyChanged;
|
||||
@@ -143,6 +150,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
public ObservableCollection<AdvancedPasteCustomAction> CustomActions => _customActions;
|
||||
|
||||
public AdvancedPasteAdditionalActions AdditionalActions => _additionalActions;
|
||||
|
||||
private bool OpenAIKeyExists()
|
||||
{
|
||||
PasswordVault vault = new PasswordVault();
|
||||
@@ -336,12 +345,16 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsConflictingCopyShortcut
|
||||
{
|
||||
get => _customActions.Select(customAction => customAction.Shortcut)
|
||||
.Concat([PasteAsPlainTextShortcut, AdvancedPasteUIShortcut, PasteAsMarkdownShortcut, PasteAsJsonShortcut])
|
||||
.Any(hotkey => WarnHotkeys.Contains(hotkey.ToString()));
|
||||
}
|
||||
public bool IsConflictingCopyShortcut =>
|
||||
_customActions.Select(customAction => customAction.Shortcut)
|
||||
.Concat([PasteAsPlainTextShortcut, AdvancedPasteUIShortcut, PasteAsMarkdownShortcut, PasteAsJsonShortcut])
|
||||
.Any(hotkey => WarnHotkeys.Contains(hotkey.ToString()));
|
||||
|
||||
public bool IsAdditionalActionConflictingCopyShortcut =>
|
||||
_additionalActions.AllActions
|
||||
.OfType<AdvancedPasteAdditionalAction>()
|
||||
.Select(additionalAction => additionalAction.Shortcut)
|
||||
.Any(hotkey => WarnHotkeys.Contains(hotkey.ToString()));
|
||||
|
||||
private void DelayedTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
@@ -461,6 +474,16 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
NotifySettingsChanged();
|
||||
}
|
||||
|
||||
private void OnAdditionalActionPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
SaveAndNotifySettings();
|
||||
|
||||
if (e.PropertyName == nameof(AdvancedPasteAdditionalAction.Shortcut))
|
||||
{
|
||||
OnPropertyChanged(nameof(IsAdditionalActionConflictingCopyShortcut));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCustomActionPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (typeof(AdvancedPasteCustomAction).GetProperty(e.PropertyName).GetCustomAttribute<JsonIgnoreAttribute>() == null)
|
||||
|
||||
Reference in New Issue
Block a user