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