diff --git a/Flow.Launcher.Infrastructure/Hotkey/IHotkeySettings.cs b/Flow.Launcher.Infrastructure/Hotkey/IHotkeySettings.cs index 295a569ee..448a70d19 100644 --- a/Flow.Launcher.Infrastructure/Hotkey/IHotkeySettings.cs +++ b/Flow.Launcher.Infrastructure/Hotkey/IHotkeySettings.cs @@ -2,7 +2,16 @@ namespace Flow.Launcher.Infrastructure.Hotkey; +/// +/// Interface that you should implement in your settings class to be able to pass it to +/// Flow.Launcher.HotkeyControlDialog. It allows the dialog to display the hotkeys that have already been +/// registered, and optionally provide a way to unregister them. +/// public interface IHotkeySettings { + /// + /// A list of hotkeys that have already been registered. The dialog will display these hotkeys and provide a way to + /// unregister them. + /// public List RegisteredHotkeys { get; } } diff --git a/Flow.Launcher.Infrastructure/Hotkey/RegisteredHotkeyData.cs b/Flow.Launcher.Infrastructure/Hotkey/RegisteredHotkeyData.cs index 7fa7421cd..b6a10fc30 100644 --- a/Flow.Launcher.Infrastructure/Hotkey/RegisteredHotkeyData.cs +++ b/Flow.Launcher.Infrastructure/Hotkey/RegisteredHotkeyData.cs @@ -4,16 +4,116 @@ namespace Flow.Launcher.Infrastructure.Hotkey; #nullable enable +/// +/// Represents a hotkey that has been registered. Used in Flow.Launcher.HotkeyControlDialog via +/// and to display errors if user tries to register a hotkey +/// that has already been registered, and optionally provides a way to unregister the hotkey. +/// public record RegisteredHotkeyData { + /// + /// representation of this hotkey. + /// public HotkeyModel Hotkey { get; } - public string Description { get; } + + /// + /// String key in the localization dictionary that represents this hotkey. For example, ReloadPluginHotkey, + /// which represents the string "Reload Plugins Data" in en.xaml + /// + public string DescriptionResourceKey { get; } + + /// + /// Array of values that will replace {0}, {1}, {2}, etc. in the localized string found via + /// . + /// + public object?[] DescriptionFormatVariables { get; } = Array.Empty(); + + /// + /// An action that, when called, will unregister this hotkey. If it's null, it's assumed that + /// this hotkey can't be unregistered, and the "Overwrite" option will not appear in the hotkey dialog. + /// public Action? RemoveHotkey { get; } - public RegisteredHotkeyData(string hotkey, string description, Action? removeHotkey = null) + /// + /// Creates an instance of RegisteredHotkeyData. Assumes that the key specified in + /// descriptionResourceKey doesn't need any arguments for string.Format. If it does, + /// use one of the other constructors. + /// + /// + /// The hotkey this class will represent. + /// Example values: F1, Ctrl+Shift+Enter + /// + /// + /// The key in the localization dictionary that represents this hotkey. For example, ReloadPluginHotkey, + /// which represents the string "Reload Plugins Data" in en.xaml + /// + /// + /// An action that, when called, will unregister this hotkey. If it's null, it's assumed that this hotkey + /// can't be unregistered, and the "Overwrite" option will not appear in the hotkey dialog. + /// + public RegisteredHotkeyData(string hotkey, string descriptionResourceKey, Action? removeHotkey = null) { Hotkey = new HotkeyModel(hotkey); - Description = description; + DescriptionResourceKey = descriptionResourceKey; + RemoveHotkey = removeHotkey; + } + + /// + /// Creates an instance of RegisteredHotkeyData. Assumes that the key specified in + /// descriptionResourceKey needs exactly one argument for string.Format. + /// + /// + /// The hotkey this class will represent. + /// Example values: F1, Ctrl+Shift+Enter + /// + /// + /// The key in the localization dictionary that represents this hotkey. For example, ReloadPluginHotkey, + /// which represents the string "Reload Plugins Data" in en.xaml + /// + /// + /// The value that will replace {0} in the localized string found via description. + /// + /// + /// An action that, when called, will unregister this hotkey. If it's null, it's assumed that this hotkey + /// can't be unregistered, and the "Overwrite" option will not appear in the hotkey dialog. + /// + public RegisteredHotkeyData( + string hotkey, string descriptionResourceKey, object? descriptionFormatVariable, Action? removeHotkey = null + ) + { + Hotkey = new HotkeyModel(hotkey); + DescriptionResourceKey = descriptionResourceKey; + DescriptionFormatVariables = new[] { descriptionFormatVariable }; + RemoveHotkey = removeHotkey; + } + + /// + /// Creates an instance of RegisteredHotkeyData. Assumes that the key specified in + /// needs multiple arguments for string.Format. + /// + /// + /// The hotkey this class will represent. + /// Example values: F1, Ctrl+Shift+Enter + /// + /// + /// The key in the localization dictionary that represents this hotkey. For example, ReloadPluginHotkey, + /// which represents the string "Reload Plugins Data" in en.xaml + /// + /// + /// Array of values that will replace {0}, {1}, {2}, etc. + /// in the localized string found via description. + /// + /// + /// An action that, when called, will unregister this hotkey. If it's null, it's assumed that this hotkey + /// can't be unregistered, and the "Overwrite" option will not appear in the hotkey dialog. + /// + public RegisteredHotkeyData( + string hotkey, string descriptionResourceKey, object?[] descriptionFormatVariables, Action? removeHotkey = null + ) + { + Hotkey = new HotkeyModel(hotkey); + DescriptionResourceKey = descriptionResourceKey; + DescriptionFormatVariables = descriptionFormatVariables; RemoveHotkey = removeHotkey; } } diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index b890304e8..58b1cc467 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -282,65 +282,69 @@ namespace Flow.Launcher.Infrastructure.UserSettings { var list = new List { - new("Escape", "Escape"), // TODO - new("F5", "ReloadPluginHotkey"), // TODO - new("Alt+Home", "Select last result"), // TODO - new("Alt+End", "Select last result"), // TODO - new("Ctrl+R", "Requery"), // TODO - new("Ctrl+H", "ToggleHistoryHotkey"), // TODO - new("Ctrl+OemCloseBrackets", "QuickWidthHotkey"), // TODO - new("Ctrl+OemOpenBrackets", "QuickWidthHotkey"), // TODO - new("Ctrl+OemPlus", "QuickHeightHotkey"), // TODO - new("Ctrl+OemMinus", "QuickHeightHotkey"), // TODO - new("Ctrl+Shift+Enter", "HotkeyCtrlShiftEnterDesc"), // TODO - new("Shift+Enter", "OpenContextMenuHotkey"), // TODO - new("Enter", "HotkeyRunDesc"), // TODO - new("Ctrl+Enter", "Open result"), // TODO - new("Alt+Enter", "Open result"), // TODO - new("Ctrl+F12", "ToggleGameModeHotkey"), // TODO - new("Ctrl+Shift+C", "Copy alternative"), // TODO + new("Up", "HotkeyLeftRightDesc"), + new("Down", "HotkeyLeftRightDesc"), + new("Left", "HotkeyUpDownDesc"), + new("Right", "HotkeyUpDownDesc"), + new("Escape", "HotkeyESCDesc"), + new("F5", "ReloadPluginHotkey"), + new("Alt+Home", "HotkeySelectFirstResult"), + new("Alt+End", "HotkeySelectLastResult"), + new("Ctrl+R", "HotkeyRequery"), + new("Ctrl+H", "ToggleHistoryHotkey"), + new("Ctrl+OemCloseBrackets", "QuickWidthHotkey"), + new("Ctrl+OemOpenBrackets", "QuickWidthHotkey"), + new("Ctrl+OemPlus", "QuickHeightHotkey"), + new("Ctrl+OemMinus", "QuickHeightHotkey"), + new("Ctrl+Shift+Enter", "HotkeyCtrlShiftEnterDesc"), + new("Shift+Enter", "OpenContextMenuHotkey"), + new("Enter", "HotkeyRunDesc"), + new("Ctrl+Enter", "OpenContainFolderHotkey"), + new("Alt+Enter", "HotkeyOpenResult"), + new("Ctrl+F12", "ToggleGameModeHotkey"), + new("Ctrl+Shift+C", "CopyFilePathHotkey"), - new($"{OpenResultModifiers}+D1", "Open Result"), // TODO - new($"{OpenResultModifiers}+D2", "Open Result"), // TODO - new($"{OpenResultModifiers}+D3", "Open Result"), // TODO - new($"{OpenResultModifiers}+D4", "Open Result"), // TODO - new($"{OpenResultModifiers}+D5", "Open Result"), // TODO - new($"{OpenResultModifiers}+D6", "Open Result"), // TODO - new($"{OpenResultModifiers}+D7", "Open Result"), // TODO - new($"{OpenResultModifiers}+D8", "Open Result"), // TODO - new($"{OpenResultModifiers}+D9", "Open Result"), // TODO - new($"{OpenResultModifiers}+D0", "Open Result"), // TODO + new($"{OpenResultModifiers}+D1", "HotkeyOpenResultN", 1), + new($"{OpenResultModifiers}+D2", "HotkeyOpenResultN", 2), + new($"{OpenResultModifiers}+D3", "HotkeyOpenResultN", 3), + new($"{OpenResultModifiers}+D4", "HotkeyOpenResultN", 4), + new($"{OpenResultModifiers}+D5", "HotkeyOpenResultN", 5), + new($"{OpenResultModifiers}+D6", "HotkeyOpenResultN", 6), + new($"{OpenResultModifiers}+D7", "HotkeyOpenResultN", 7), + new($"{OpenResultModifiers}+D8", "HotkeyOpenResultN", 8), + new($"{OpenResultModifiers}+D9", "HotkeyOpenResultN", 9), + new($"{OpenResultModifiers}+D0", "HotkeyOpenResultN", 10) }; if(!string.IsNullOrEmpty(Hotkey)) - list.Add(new(Hotkey, "Open main window", () => Hotkey = "")); // TODO + list.Add(new(Hotkey, "flowlauncherHotkey", () => Hotkey = "")); if(!string.IsNullOrEmpty(PreviewHotkey)) - list.Add(new(PreviewHotkey, "Preview Hotkey", () => PreviewHotkey = "")); // TODO + list.Add(new(PreviewHotkey, "previewHotkey", () => PreviewHotkey = "")); if(!string.IsNullOrEmpty(AutoCompleteHotkey)) - list.Add(new(AutoCompleteHotkey, "AutoCompleteHotkey", () => AutoCompleteHotkey = "")); // TODO + list.Add(new(AutoCompleteHotkey, "autoCompleteHotkey", () => AutoCompleteHotkey = "")); if(!string.IsNullOrEmpty(AutoCompleteHotkey2)) - list.Add(new(AutoCompleteHotkey2, "AutoCompleteHotkey", () => AutoCompleteHotkey2 = "")); // TODO + list.Add(new(AutoCompleteHotkey2, "autoCompleteHotkey", () => AutoCompleteHotkey2 = "")); if(!string.IsNullOrEmpty(SelectNextItemHotkey)) - list.Add(new(SelectNextItemHotkey, "SelectNextItemHotkey", () => SelectNextItemHotkey = "")); // TODO + list.Add(new(SelectNextItemHotkey, "SelectNextItemHotkey", () => SelectNextItemHotkey = "")); if(!string.IsNullOrEmpty(SelectNextItemHotkey2)) - list.Add(new(SelectNextItemHotkey2, "SelectNextItemHotkey", () => SelectNextItemHotkey2 = "")); // TODO + list.Add(new(SelectNextItemHotkey2, "SelectNextItemHotkey", () => SelectNextItemHotkey2 = "")); if(!string.IsNullOrEmpty(SelectPrevItemHotkey)) - list.Add(new(SelectPrevItemHotkey, "SelectPrevItemHotkey", () => SelectPrevItemHotkey = "")); // TODO + list.Add(new(SelectPrevItemHotkey, "SelectPrevItemHotkey", () => SelectPrevItemHotkey = "")); if(!string.IsNullOrEmpty(SelectPrevItemHotkey2)) - list.Add(new(SelectPrevItemHotkey2, "SelectPrevItemHotkey", () => SelectPrevItemHotkey2 = "")); // TODO + list.Add(new(SelectPrevItemHotkey2, "SelectPrevItemHotkey", () => SelectPrevItemHotkey2 = "")); if(!string.IsNullOrEmpty(SettingWindowHotkey)) - list.Add(new(SettingWindowHotkey, "SettingWindowHotkey", () => SettingWindowHotkey = "")); // TODO + list.Add(new(SettingWindowHotkey, "SettingWindowHotkey", () => SettingWindowHotkey = "")); if(!string.IsNullOrEmpty(OpenContextMenuHotkey)) - list.Add(new(OpenContextMenuHotkey, "OpenContextMenuHotkey", () => OpenContextMenuHotkey = "")); // TODO + list.Add(new(OpenContextMenuHotkey, "OpenContextMenuHotkey", () => OpenContextMenuHotkey = "")); if(!string.IsNullOrEmpty(SelectNextPageHotkey)) - list.Add(new(SelectNextPageHotkey, "SelectNextPageHotkey", () => SelectNextPageHotkey = "")); // TODO + list.Add(new(SelectNextPageHotkey, "SelectNextPageHotkey", () => SelectNextPageHotkey = "")); if(!string.IsNullOrEmpty(SelectPrevPageHotkey)) - list.Add(new(SelectPrevPageHotkey, "SelectPrevPageHotkey", () => SelectPrevPageHotkey = "")); // TODO + list.Add(new(SelectPrevPageHotkey, "SelectPrevPageHotkey", () => SelectPrevPageHotkey = "")); foreach (var customPluginHotkey in CustomPluginHotkeys) { if (!string.IsNullOrEmpty(customPluginHotkey.Hotkey)) - list.Add(new(customPluginHotkey.Hotkey, "Custom plugin hotkey", () => customPluginHotkey.Hotkey = "")); // TODO + list.Add(new(customPluginHotkey.Hotkey, "customQueryHotkey", () => customPluginHotkey.Hotkey = "")); } return list; diff --git a/Flow.Launcher/HotkeyControlDialog.xaml.cs b/Flow.Launcher/HotkeyControlDialog.xaml.cs index df2f38931..a7b99f670 100644 --- a/Flow.Launcher/HotkeyControlDialog.xaml.cs +++ b/Flow.Launcher/HotkeyControlDialog.xaml.cs @@ -119,12 +119,16 @@ public partial class HotkeyControlDialog : ContentDialog if (_hotkeySettings.RegisteredHotkeys.FirstOrDefault(v => v.Hotkey == hotkey) is { } registeredHotkeyData) { + var description = string.Format( + InternationalizationManager.Instance.GetTranslation(registeredHotkeyData.DescriptionResourceKey), + registeredHotkeyData.DescriptionFormatVariables + ); Alert.Visibility = Visibility.Visible; if (registeredHotkeyData.RemoveHotkey is not null) { tbMsg.Text = string.Format( InternationalizationManager.Instance.GetTranslation("hotkeyUnavailableEditable"), - registeredHotkeyData.Description + description ); SaveBtn.IsEnabled = false; SaveBtn.Visibility = Visibility.Collapsed; @@ -136,7 +140,7 @@ public partial class HotkeyControlDialog : ContentDialog { tbMsg.Text = string.Format( InternationalizationManager.Instance.GetTranslation("hotkeyUnavailableUneditable"), - registeredHotkeyData.Description + description ); SaveBtn.IsEnabled = false; SaveBtn.Visibility = Visibility.Visible; diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 635d4f399..52b943177 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -398,6 +398,12 @@ Open Setting Window Reload Plugin Data + Select first result + Select last result + Run current query again + Open result + Open result #{0} + Weather Weather in Google Result > ping 8.8.8.8