diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 54f6506d9..a32f1d682 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -364,8 +364,16 @@ namespace Flow.Launcher.Core.Plugin NonGlobalPlugins[newActionKeyword] = plugin; } - // Update action keywords in plugin metadata + // Update action keywords and action keyword in plugin metadata plugin.Metadata.ActionKeywords.Add(newActionKeyword); + if (plugin.Metadata.ActionKeywords.Count > 0) + { + plugin.Metadata.ActionKeyword = plugin.Metadata.ActionKeywords[0]; + } + else + { + plugin.Metadata.ActionKeyword = string.Empty; + } } /// @@ -386,67 +394,15 @@ namespace Flow.Launcher.Core.Plugin if (oldActionkeyword != Query.GlobalPluginWildcardSign) NonGlobalPlugins.Remove(oldActionkeyword); - // Update action keywords in plugin metadata + // Update action keywords and action keyword in plugin metadata plugin.Metadata.ActionKeywords.Remove(oldActionkeyword); - } - - public static void ReplaceActionKeyword(string id, IReadOnlyList oldActionKeywords, IReadOnlyList newActionKeywords) - { - if (CheckActionKeywordChanged(oldActionKeywords, newActionKeywords)) + if (plugin.Metadata.ActionKeywords.Count > 0) { - // Fix collection modified while iterating exception - var oldActionKeywordsClone = oldActionKeywords.ToList(); - foreach (var actionKeyword in oldActionKeywordsClone) - { - RemoveActionKeyword(id, actionKeyword); - } - foreach (var actionKeyword in newActionKeywords) - { - AddActionKeyword(id, actionKeyword); - } - - // Update action keyword in plugin metadata - var plugin = GetPluginForId(id); - if (newActionKeywords.Count > 0) - { - plugin.Metadata.ActionKeyword = newActionKeywords[0]; - } - else - { - plugin.Metadata.ActionKeyword = string.Empty; - } + plugin.Metadata.ActionKeyword = plugin.Metadata.ActionKeywords[0]; } - } - - private static bool CheckActionKeywordChanged(IReadOnlyList oldActionKeywords, IReadOnlyList newActionKeywords) - { - if (oldActionKeywords.Count != newActionKeywords.Count) - return true; - - var sortedOldActionKeywords = oldActionKeywords.OrderBy(s => s).ToList(); - var sortedNewActionKeywords = newActionKeywords.OrderBy(s => s).ToList(); - - return !sortedOldActionKeywords.SequenceEqual(sortedNewActionKeywords); - } - - public static void ReplaceActionKeyword(string id, string oldActionKeyword, string newActionKeyword) - { - if (oldActionKeyword != newActionKeyword) + else { - RemoveActionKeyword(id, oldActionKeyword); - AddActionKeyword(id, newActionKeyword); - - // Update action keyword in plugin metadata - var plugin = GetPluginForId(id); - var newActionKeywords = plugin.Metadata.ActionKeywords; - if (newActionKeywords.Count > 0) - { - plugin.Metadata.ActionKeyword = newActionKeywords[0]; - } - else - { - plugin.Metadata.ActionKeyword = string.Empty; - } + plugin.Metadata.ActionKeyword = string.Empty; } } diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs index da6bb598b..4d424dc0b 100644 --- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs @@ -189,14 +189,14 @@ namespace Flow.Launcher.Plugin Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null, CancellationToken token = default); /// - /// Add ActionKeyword for specific plugin + /// Add ActionKeyword and update action keyword metadata for specific plugin /// /// ID for plugin that needs to add action keyword /// The actionkeyword that is supposed to be added void AddActionKeyword(string pluginId, string newActionKeyword); /// - /// Remove ActionKeyword for specific plugin + /// Remove ActionKeyword and update action keyword metadata for specific plugin /// /// ID for plugin that needs to remove action keyword /// The actionkeyword that is supposed to be removed @@ -333,13 +333,5 @@ namespace Flow.Launcher.Plugin /// When user closes the progress box manually by button or esc key, this action will be called. /// A progress box interface. public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null); - - /// - /// Replace ActionKeyword for specific plugin - /// - /// ID for plugin that needs to remove action keyword - /// The actionkeyword that is supposed to be removed - /// The actionkeyword that is supposed to be added - public void ReplaceActionKeyword(string pluginId, string oldActionKeyword, string newActionKeyword); } } diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs index 6ea1dae50..10f3cf4e9 100644 --- a/Flow.Launcher/ActionKeywords.xaml.cs +++ b/Flow.Launcher/ActionKeywords.xaml.cs @@ -45,8 +45,24 @@ namespace Flow.Launcher if (!newActionKeywords.Except(oldActionKeywords).Any(PluginManager.ActionKeywordRegistered)) { - pluginViewModel.ChangeActionKeyword(newActionKeywords, oldActionKeywords); - Close(); + if (oldActionKeywords.Count != newActionKeywords.Count) + { + ReplaceActionKeyword(plugin.Metadata.ID, oldActionKeywords, newActionKeywords); + } + + var sortedOldActionKeywords = oldActionKeywords.OrderBy(s => s).ToList(); + var sortedNewActionKeywords = newActionKeywords.OrderBy(s => s).ToList(); + + if (sortedOldActionKeywords.SequenceEqual(sortedNewActionKeywords)) + { + // User just changes the sequence of action keywords + var msg = translater.GetTranslation("newActionKeywordsSameAsOld"); + MessageBoxEx.Show(msg); + } + else + { + ReplaceActionKeyword(plugin.Metadata.ID, oldActionKeywords, newActionKeywords); + } } else { @@ -54,5 +70,24 @@ namespace Flow.Launcher MessageBoxEx.Show(msg); } } + + private void ReplaceActionKeyword(string id, IReadOnlyList oldActionKeywords, IReadOnlyList newActionKeywords) + { + // Because add & remove action keyword will change action keyword metadata, + // so we need to clone it to fix collection modified while iterating exception + var oldActionKeywordsClone = oldActionKeywords.ToList(); + foreach (var actionKeyword in oldActionKeywordsClone) + { + PluginManager.RemoveActionKeyword(id, actionKeyword); + } + foreach (var actionKeyword in newActionKeywords) + { + PluginManager.AddActionKeyword(id, actionKeyword); + } + + // Update action keywords text and close + pluginViewModel.OnActionKeywordsChanged(); + Close(); + } } } diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 282d0fb47..b1575b252 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -333,6 +333,7 @@ Can't find specified plugin New Action Keyword can't be empty This new Action Keyword is already assigned to another plugin, please choose a different one + This new Action Keyword is the same as old, please choose a different one Success Completed successfully Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords. diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index b6f3b0d27..248688f76 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -326,8 +326,6 @@ namespace Flow.Launcher public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, forceClosed); - public void ReplaceActionKeyword(string pluginId, string oldActionKeyword, string newActionKeyword) => PluginManager.ReplaceActionKeyword(pluginId, oldActionKeyword, newActionKeyword); - #endregion #region Private Methods diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index 63263c768..c726cc343 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -110,9 +110,8 @@ namespace Flow.Launcher.ViewModel public int Priority => PluginPair.Metadata.Priority; public Infrastructure.UserSettings.Plugin PluginSettingsObject { get; set; } - public void ChangeActionKeyword(IReadOnlyList newActionKeywords, IReadOnlyList oldActionKeywords) + public void OnActionKeywordsChanged() { - PluginManager.ReplaceActionKeyword(PluginPair.Metadata.ID, oldActionKeywords, newActionKeywords); OnPropertyChanged(nameof(ActionKeywordsText)); } @@ -158,5 +157,4 @@ namespace Flow.Launcher.ViewModel changeKeywordsWindow.ShowDialog(); } } - } diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs index d3d18d0d2..58577dbc1 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs @@ -15,7 +15,6 @@ namespace Flow.Launcher.Plugin.WebSearch private SearchSourceViewModel _viewModel; private string selectedNewIconImageFullPath; - public SearchSourceSettingWindow(IList sources, PluginInitContext context, SearchSource old) { _oldSearchSource = old; @@ -102,7 +101,8 @@ namespace Flow.Launcher.Plugin.WebSearch if (!_context.API.ActionKeywordAssigned(newKeyword) || oldKeyword == newKeyword) { var id = _context.CurrentPluginMetadata.ID; - _context.API.ReplaceActionKeyword(id, oldKeyword, newKeyword); + _context.API.RemoveActionKeyword(id, oldKeyword); + _context.API.AddActionKeyword(id, newKeyword); var index = _searchSources.IndexOf(_oldSearchSource); _searchSources[index] = _searchSource;