Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 32 additions & 18 deletions Flow.Launcher.Core/Plugin/PluginManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Microsoft.AspNetCore.Routing;

namespace Flow.Launcher.Core.Plugin
{
Expand All @@ -21,7 +22,7 @@ public static class PluginManager

public static List<PluginPair> AllPlugins { get; private set; }
public static readonly List<PluginPair> GlobalPlugins = new List<PluginPair>();
public static readonly Dictionary<string, PluginPair> NonGlobalPlugins = new Dictionary<string, PluginPair>();
public static readonly Dictionary<string, List<PluginPair>> NonGlobalPlugins = new Dictionary<string, List<PluginPair>>();

public static IPublicAPI API { private set; get; }

Expand Down Expand Up @@ -54,7 +55,7 @@ public static void Save()

public static void ReloadData()
{
foreach(var plugin in AllPlugins)
foreach (var plugin in AllPlugins)
{
var reloadablePlugin = plugin.Plugin as IReloadable;
reloadablePlugin?.ReloadData();
Expand Down Expand Up @@ -108,7 +109,7 @@ public static void InitializePlugins(IPublicAPI api)
catch (Exception e)
{
Log.Exception(nameof(PluginManager), $"Fail to Init plugin: {pair.Metadata.Name}", e);
pair.Metadata.Disabled = true;
pair.Metadata.Disabled = true;
failedPlugins.Enqueue(pair);
}
});
Expand All @@ -123,7 +124,17 @@ public static void InitializePlugins(IPublicAPI api)
plugin.Metadata.ActionKeywords
.Where(x => x != Query.GlobalPluginWildcardSign)
.ToList()
.ForEach(x => NonGlobalPlugins[x] = plugin);
.ForEach(x =>
{
if (NonGlobalPlugins.ContainsKey(x))
{
NonGlobalPlugins[x].Add(plugin);
}
else
{
NonGlobalPlugins[x] = new List<PluginPair> { plugin };
}
});
}

if (failedPlugins.Any())
Expand All @@ -142,8 +153,7 @@ public static List<PluginPair> ValidPluginsForQuery(Query query)
{
if (NonGlobalPlugins.ContainsKey(query.ActionKeyword))
{
var plugin = NonGlobalPlugins[query.ActionKeyword];
return new List<PluginPair> { plugin };
return NonGlobalPlugins[query.ActionKeyword];
}
else
{
Expand Down Expand Up @@ -233,11 +243,6 @@ public static List<Result> GetContextMenusForPlugin(Result result)
return results;
}

public static bool ActionKeywordRegistered(string actionKeyword)
{
return actionKeyword != Query.GlobalPluginWildcardSign
&& NonGlobalPlugins.ContainsKey(actionKeyword);
}

/// <summary>
/// used to add action keyword for multiple action keyword plugin
Expand All @@ -252,7 +257,14 @@ public static void AddActionKeyword(string id, string newActionKeyword)
}
else
{
NonGlobalPlugins[newActionKeyword] = plugin;
if (NonGlobalPlugins.ContainsKey(newActionKeyword))
{
NonGlobalPlugins[newActionKeyword].Add(plugin);
}
else
{
NonGlobalPlugins[newActionKeyword] = new List<PluginPair> { plugin };
}
}
plugin.Metadata.ActionKeywords.Add(newActionKeyword);
}
Expand All @@ -268,15 +280,17 @@ public static void RemoveActionKeyword(string id, string oldActionkeyword)
&& // Plugins may have multiple ActionKeywords that are global, eg. WebSearch
plugin.Metadata.ActionKeywords
.Where(x => x == Query.GlobalPluginWildcardSign)
.ToList()
.Count == 1)
.Count() == 1)
{
GlobalPlugins.Remove(plugin);
}

if (oldActionkeyword != Query.GlobalPluginWildcardSign)
NonGlobalPlugins.Remove(oldActionkeyword);


if (oldActionkeyword != Query.GlobalPluginWildcardSign
&& plugin.Metadata.ActionKeywords.Where(x => x == oldActionkeyword).Count() == 1)
{
NonGlobalPlugins[oldActionkeyword].Remove(plugin);
}


plugin.Metadata.ActionKeywords.Remove(oldActionkeyword);
}
Expand Down
5 changes: 3 additions & 2 deletions Flow.Launcher.Core/Plugin/QueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Flow.Launcher.Core.Plugin
{
public static class QueryBuilder
{
public static Query Build(string text, Dictionary<string, PluginPair> nonGlobalPlugins)
public static Query Build(string text, Dictionary<string, List<PluginPair>> nonGlobalPlugins)
{
// replace multiple white spaces with one white space
var terms = text.Split(new[] { Query.TermSeperater }, StringSplitOptions.RemoveEmptyEntries);
Expand All @@ -20,7 +20,8 @@ public static Query Build(string text, Dictionary<string, PluginPair> nonGlobalP
string actionKeyword, search;
string possibleActionKeyword = terms[0];
List<string> actionParameters;
if (nonGlobalPlugins.TryGetValue(possibleActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled)
if (nonGlobalPlugins.TryGetValue(possibleActionKeyword, out var pluginPairs)
&& pluginPairs.Any(pluginPair => !pluginPair.Metadata.Disabled))
{ // use non global plugin for query
actionKeyword = possibleActionKeyword;
actionParameters = terms.Skip(1).ToList();
Expand Down
10 changes: 5 additions & 5 deletions Flow.Launcher.Test/QueryBuilderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ public class QueryBuilderTest
[Test]
public void ExclusivePluginQueryTest()
{
var nonGlobalPlugins = new Dictionary<string, PluginPair>
var nonGlobalPlugins = new Dictionary<string, List<PluginPair>>
{
{">", new PluginPair {Metadata = new PluginMetadata {ActionKeywords = new List<string> {">"}}}}
{">", new List<PluginPair>{ new PluginPair {Metadata = new PluginMetadata { ActionKeywords = new List<string> { ">" } } }}}
};

Query q = QueryBuilder.Build("> file.txt file2 file3", nonGlobalPlugins);
Expand All @@ -24,9 +24,9 @@ public void ExclusivePluginQueryTest()
[Test]
public void ExclusivePluginQueryIgnoreDisabledTest()
{
var nonGlobalPlugins = new Dictionary<string, PluginPair>
var nonGlobalPlugins = new Dictionary<string, List<PluginPair>>
{
{">", new PluginPair {Metadata = new PluginMetadata {ActionKeywords = new List<string> {">"}, Disabled = true}}}
{">", new List<PluginPair>{new PluginPair {Metadata = new PluginMetadata {ActionKeywords = new List<string> {">"}, Disabled = true}} } }
};

Query q = QueryBuilder.Build("> file.txt file2 file3", nonGlobalPlugins);
Expand All @@ -37,7 +37,7 @@ public void ExclusivePluginQueryIgnoreDisabledTest()
[Test]
public void GenericPluginQueryTest()
{
Query q = QueryBuilder.Build("file.txt file2 file3", new Dictionary<string, PluginPair>());
Query q = QueryBuilder.Build("file.txt file2 file3", new Dictionary<string, List<PluginPair>>());

Assert.AreEqual("file.txt file2 file3", q.Search);
Assert.AreEqual("", q.ActionKeyword);
Expand Down
13 changes: 3 additions & 10 deletions Flow.Launcher/ActionKeywords.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,9 @@ private void btnDone_OnClick(object sender, RoutedEventArgs _)
var oldActionKeyword = plugin.Metadata.ActionKeywords[0];
var newActionKeyword = tbAction.Text.Trim();
newActionKeyword = newActionKeyword.Length > 0 ? newActionKeyword : "*";
if (!pluginViewModel.IsActionKeywordRegistered(newActionKeyword))
{
pluginViewModel.ChangeActionKeyword(newActionKeyword, oldActionKeyword);
Close();
}
else
{
string msg = translater.GetTranslation("newActionKeywordsHasBeenAssigned");
MessageBox.Show(msg);
}
pluginViewModel.ChangeActionKeyword(newActionKeyword, oldActionKeyword);
Close();

}
}
}
6 changes: 3 additions & 3 deletions Flow.Launcher/ViewModel/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -450,18 +450,18 @@ private void RemoveOldQueryResults(Query query)
{
if (!string.IsNullOrEmpty(keyword))
{
Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata);
Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Select(p=>p.Metadata));
}
}
else
{
if (string.IsNullOrEmpty(keyword))
{
Results.RemoveResultsFor(PluginManager.NonGlobalPlugins[lastKeyword].Metadata);
Results.RemoveResultsFor(PluginManager.NonGlobalPlugins[lastKeyword].Select(p => p.Metadata));
}
else if (lastKeyword != keyword)
{
Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata);
Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Select(p => p.Metadata));
}
}
}
Expand Down
1 change: 0 additions & 1 deletion Flow.Launcher/ViewModel/PluginViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,5 @@ public void ChangeActionKeyword(string newActionKeyword, string oldActionKeyword
OnPropertyChanged(nameof(ActionKeywordsText));
}

public bool IsActionKeywordRegistered(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
}
}
10 changes: 6 additions & 4 deletions Flow.Launcher/ViewModel/ResultsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,16 @@ public void Clear()
Results.Clear();
}

public void RemoveResultsExcept(PluginMetadata metadata)
public void RemoveResultsExcept(IEnumerable<PluginMetadata> metadatas)
{
Results.RemoveAll(r => r.Result.PluginID != metadata.ID);
var ids = metadatas.Select(m => m.ID).ToHashSet();
Results.RemoveAll(r => !ids.Contains(r.Result.PluginID));
}

public void RemoveResultsFor(PluginMetadata metadata)
public void RemoveResultsFor(IEnumerable<PluginMetadata> metadatas)
{
Results.RemoveAll(r => r.Result.PluginID == metadata.ID);
var ids = metadatas.Select(m => m.ID).ToHashSet();
Results.RemoveAll(r => ids.Contains(r.Result.PluginID));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ internal void UpdateActionKeyword(string newActionKeyword, string oldActionKeywo
Settings.SearchActionKeyword = newActionKeyword;
}

internal bool IsActionKeywordAlreadyAssigned(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);

internal bool IsNewActionKeywordGlobal(string newActionKeyword) => newActionKeyword == Query.GlobalPluginWildcardSign;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public ActionKeywordSetting(SettingsViewModel settingsViewModel, List<ActionKeyw

txtCurrentActionKeyword.Text = selectedActionKeyword.Keyword;

this.actionKeywordListView = actionKeywordListView;
this.actionKeywordListView = actionKeywordListView;
}

private void OnConfirmButtonClick(object sender, RoutedEventArgs e)
Expand All @@ -52,27 +52,23 @@ private void OnConfirmButtonClick(object sender, RoutedEventArgs e)
return;
}

if (settingsViewModel.IsNewActionKeywordGlobal(newActionKeyword)
&& currentActionKeyword.Description
if (settingsViewModel.IsNewActionKeywordGlobal(newActionKeyword)
&& currentActionKeyword.Description
== settingsViewModel.Context.API.GetTranslation("plugin_explorer_actionkeywordview_filecontentsearch"))
{
MessageBox.Show(settingsViewModel.Context.API.GetTranslation("plugin_explorer_globalActionKeywordInvalid"));

return;
}

if (!settingsViewModel.IsActionKeywordAlreadyAssigned(newActionKeyword))
{
settingsViewModel.UpdateActionKeyword(newActionKeyword, currentActionKeyword.Keyword);

actionKeywordListView.Where(x => x.Description == currentActionKeyword.Description).FirstOrDefault().Keyword = newActionKeyword;

Close();
settingsViewModel.UpdateActionKeyword(newActionKeyword, currentActionKeyword.Keyword);

return;
}
actionKeywordListView.Where(x => x.Description == currentActionKeyword.Description).FirstOrDefault().Keyword = newActionKeyword;

MessageBox.Show(settingsViewModel.Context.API.GetTranslation("newActionKeywordsHasBeenAssigned"));
Close();

return;
}

private void OnCancelButtonClick(object sender, RoutedEventArgs e)
Expand Down
5 changes: 4 additions & 1 deletion Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using Flow.Launcher.Core.Plugin;

namespace Flow.Launcher.Plugin.PluginIndicator
Expand All @@ -12,7 +13,9 @@ public List<Result> Query(Query query)
{
var results = from keyword in PluginManager.NonGlobalPlugins.Keys
where keyword.StartsWith(query.Terms[0])
let metadata = PluginManager.NonGlobalPlugins[keyword].Metadata
from metadata in
from plugin in PluginManager.NonGlobalPlugins[keyword]
select plugin.Metadata
where !metadata.Disabled
select new Result
{
Expand Down
43 changes: 14 additions & 29 deletions Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ public partial class SearchSourceSettingWindow
public SearchSourceSettingWindow(IList<SearchSource> sources, PluginInitContext context, SearchSource old)
{
_oldSearchSource = old;
_viewModel = new SearchSourceViewModel {SearchSource = old.DeepCopy()};
_viewModel = new SearchSourceViewModel { SearchSource = old.DeepCopy() };
Initilize(sources, context, Action.Edit);
}

public SearchSourceSettingWindow(IList<SearchSource> sources, PluginInitContext context)
{
_viewModel = new SearchSourceViewModel {SearchSource = new SearchSource()};
_viewModel = new SearchSourceViewModel { SearchSource = new SearchSource() };
Initilize(sources, context, Action.Add);
}

Expand Down Expand Up @@ -80,41 +80,26 @@ private void OnConfirmButtonClick(object sender, RoutedEventArgs e)
private void AddSearchSource()
{
var keyword = _searchSource.ActionKeyword;
if (!PluginManager.ActionKeywordRegistered(keyword))
{
var id = _context.CurrentPluginMetadata.ID;
PluginManager.AddActionKeyword(id, keyword);
var id = _context.CurrentPluginMetadata.ID;
PluginManager.AddActionKeyword(id, keyword);

_searchSources.Add(_searchSource);
_searchSources.Add(_searchSource);

Close();
}
else
{
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
MessageBox.Show(warning);
}
Close();
}

private void EditSearchSource()
{
var newKeyword = _searchSource.ActionKeyword;
var oldKeyword = _oldSearchSource.ActionKeyword;
if (!PluginManager.ActionKeywordRegistered(newKeyword) || oldKeyword == newKeyword)
{
var id = _context.CurrentPluginMetadata.ID;
PluginManager.ReplaceActionKeyword(id, oldKeyword, newKeyword);
var id = _context.CurrentPluginMetadata.ID;
PluginManager.ReplaceActionKeyword(id, oldKeyword, newKeyword);

var index = _searchSources.IndexOf(_oldSearchSource);
_searchSources[index] = _searchSource;
var index = _searchSources.IndexOf(_oldSearchSource);
_searchSources[index] = _searchSource;

Close();

Close();
}
else
{
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
MessageBox.Show(warning);
}

if (!string.IsNullOrEmpty(selectedNewIconImageFullPath))
{
Expand All @@ -128,7 +113,7 @@ private void EditSearchSource()
private void OnSelectIconClick(object sender, RoutedEventArgs e)
{
const string filter = "Image files (*.jpg, *.jpeg, *.gif, *.png, *.bmp) |*.jpg; *.jpeg; *.gif; *.png; *.bmp";
var dialog = new OpenFileDialog {InitialDirectory = Main.CustomImagesDirectory, Filter = filter};
var dialog = new OpenFileDialog { InitialDirectory = Main.CustomImagesDirectory, Filter = filter };

var result = dialog.ShowDialog();
if (result == true)
Expand All @@ -139,7 +124,7 @@ private void OnSelectIconClick(object sender, RoutedEventArgs e)
{
if (_viewModel.ShouldProvideHint(selectedNewIconImageFullPath))
MessageBox.Show(_api.GetTranslation("flowlauncher_plugin_websearch_iconpath_hint"));

imgPreviewIcon.Source = _viewModel.LoadPreviewIcon(selectedNewIconImageFullPath);
}
}
Expand Down