diff --git a/Flow.Launcher.Infrastructure/Alphabet.cs b/Flow.Launcher.Infrastructure/Alphabet.cs deleted file mode 100644 index 7e24a8206..000000000 --- a/Flow.Launcher.Infrastructure/Alphabet.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using hyjiacan.util.p4n; -using hyjiacan.util.p4n.format; -using JetBrains.Annotations; -using Flow.Launcher.Infrastructure.Logger; -using Flow.Launcher.Infrastructure.Storage; -using Flow.Launcher.Infrastructure.UserSettings; - -namespace Flow.Launcher.Infrastructure -{ - public interface IAlphabet - { - string Translate(string stringToTranslate); - } - - public class Alphabet : IAlphabet - { - private readonly HanyuPinyinOutputFormat Format = new HanyuPinyinOutputFormat(); - private ConcurrentDictionary PinyinCache; - private BinaryStorage> _pinyinStorage; - private Settings _settings; - - public void Initialize([NotNull] Settings settings) - { - _settings = settings ?? throw new ArgumentNullException(nameof(settings)); - InitializePinyinHelpers(); - } - - private void InitializePinyinHelpers() - { - Format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); - - Stopwatch.Normal("|Flow Launcher.Infrastructure.Alphabet.Initialize|Preload pinyin cache", () => - { - _pinyinStorage = new BinaryStorage>("Pinyin"); - - lock(_pinyinStorage) - { - var loaded = _pinyinStorage.TryLoad(new Dictionary()); - - PinyinCache = new ConcurrentDictionary(loaded); - } - - // force pinyin library static constructor initialize - PinyinHelper.toHanyuPinyinStringArray('T', Format); - }); - Log.Info($"|Flow Launcher.Infrastructure.Alphabet.Initialize|Number of preload pinyin combination<{PinyinCache.Count}>"); - } - - public string Translate(string str) - { - return ConvertChineseCharactersToPinyin(str); - } - - public string ConvertChineseCharactersToPinyin(string source) - { - if (!_settings.ShouldUsePinyin) - return source; - - if (string.IsNullOrEmpty(source)) - return source; - - if (!ContainsChinese(source)) - return source; - - var combination = PinyinCombination(source); - - var pinyinArray=combination.Select(x => string.Join("", x)); - var acronymArray = combination.Select(Acronym).Distinct(); - - var joinedSingleStringCombination = new StringBuilder(); - var all = acronymArray.Concat(pinyinArray); - all.ToList().ForEach(x => joinedSingleStringCombination.Append(x)); - - return joinedSingleStringCombination.ToString(); - } - - public void Save() - { - if (!_settings.ShouldUsePinyin) - { - return; - } - - lock(_pinyinStorage) - { - _pinyinStorage.Save(PinyinCache.ToDictionary(i => i.Key, i => i.Value)); - } - } - - private static string[] EmptyStringArray = new string[0]; - private static string[][] Empty2DStringArray = new string[0][]; - - /// - /// replace chinese character with pinyin, non chinese character won't be modified - /// Because we don't have words dictionary, so we can only return all possiblie pinyin combination - /// e.g. 音乐 will return yinyue and yinle - /// should be word or sentence, instead of single character. e.g. 微软 - /// - public string[][] PinyinCombination(string characters) - { - if (!_settings.ShouldUsePinyin || string.IsNullOrEmpty(characters)) - { - return Empty2DStringArray; - } - - if (!PinyinCache.ContainsKey(characters)) - { - var allPinyins = new List(); - foreach (var c in characters) - { - var pinyins = PinyinHelper.toHanyuPinyinStringArray(c, Format); - if (pinyins != null) - { - var r = pinyins.Distinct().ToArray(); - allPinyins.Add(r); - } - else - { - var r = new[] { c.ToString() }; - allPinyins.Add(r); - } - } - - var combination = allPinyins.Aggregate(Combination).Select(c => c.Split(';')).ToArray(); - PinyinCache[characters] = combination; - return combination; - } - else - { - return PinyinCache[characters]; - } - } - - public string Acronym(string[] pinyin) - { - var acronym = string.Join("", pinyin.Select(p => p[0])); - return acronym; - } - - public bool ContainsChinese(string word) - { - if (!_settings.ShouldUsePinyin) - { - return false; - } - - if (word.Length > 40) - { - //Skip strings that are too long string for Pinyin conversion. - return false; - } - - var chinese = word.Select(PinyinHelper.toHanyuPinyinStringArray) - .Any(p => p != null); - return chinese; - } - - private string[] Combination(string[] array1, string[] array2) - { - if (!_settings.ShouldUsePinyin) - { - return EmptyStringArray; - } - - var combination = ( - from a1 in array1 - from a2 in array2 - select $"{a1};{a2}" - ).ToArray(); - return combination; - } - } -} diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 410d11536..d834bd2d3 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -53,10 +53,10 @@ - + diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs new file mode 100644 index 000000000..38f1ab879 --- /dev/null +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using JetBrains.Annotations; +using Flow.Launcher.Infrastructure.Logger; +using Flow.Launcher.Infrastructure.Storage; +using Flow.Launcher.Infrastructure.UserSettings; +using ToolGood.Words.Pinyin; +using System.Threading.Tasks; + +namespace Flow.Launcher.Infrastructure +{ + public interface IAlphabet + { + string Translate(string stringToTranslate); + } + + public class PinyinAlphabet : IAlphabet + { + private ConcurrentDictionary _pinyinCache = new ConcurrentDictionary(); + private Settings _settings; + + public void Initialize([NotNull] Settings settings) + { + _settings = settings ?? throw new ArgumentNullException(nameof(settings)); + } + + + public string Translate(string content) + { + if (_settings.ShouldUsePinyin) + { + if (!_pinyinCache.ContainsKey(content)) + { + if (WordsHelper.HasChinese(content)) + { + var result = WordsHelper.GetPinyin(content, ";"); + result = GetFirstPinyinChar(result) + result.Replace(";", ""); + _pinyinCache[content] = result; + return result; + } + else + { + return content; + } + } + else + { + return _pinyinCache[content]; + } + } + else + { + return content; + } + } + + private string GetFirstPinyinChar(string content) + { + return string.Concat(content.Split(';').Select(x => x.First())); + } + } +} \ No newline at end of file diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 731dc1541..59bdbc896 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -29,7 +29,7 @@ namespace Flow.Launcher private SettingWindowViewModel _settingsVM; private readonly Updater _updater = new Updater(Flow.Launcher.Properties.Settings.Default.GithubRepo); private readonly Portable _portable = new Portable(); - private readonly Alphabet _alphabet = new Alphabet(); + private readonly PinyinAlphabet _alphabet = new PinyinAlphabet(); private StringMatcher _stringMatcher; [STAThread] diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 23f5d85b7..0cc5a0e5d 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -21,11 +21,11 @@ namespace Flow.Launcher { private readonly SettingWindowViewModel _settingsVM; private readonly MainViewModel _mainVM; - private readonly Alphabet _alphabet; + private readonly PinyinAlphabet _alphabet; #region Constructor - public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, Alphabet alphabet) + public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, PinyinAlphabet alphabet) { _settingsVM = settingsVM; _mainVM = mainVM; @@ -76,7 +76,6 @@ namespace Flow.Launcher _settingsVM.Save(); PluginManager.Save(); ImageLoader.Save(); - _alphabet.Save(); } public void ReloadAllPluginData() diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs index 1149042dd..790c03686 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs @@ -19,10 +19,8 @@ namespace Flow.Launcher.Plugin.BrowserBookmark set { m_Name = value; - PinyinName = m_Name.Unidecode(); } } - public string PinyinName { get; private set; } public string Url { get; set; } public string Source { get; set; } public int Score { get; set; } diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs index 7c2db8bf9..c7013aa67 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs @@ -6,19 +6,19 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Commands { internal static class Bookmarks { - internal static bool MatchProgram(Bookmark bookmark, string queryString) + internal static MatchResult MatchProgram(Bookmark bookmark, string queryString) { - if (StringMatcher.FuzzySearch(queryString, bookmark.Name).IsSearchPrecisionScoreMet()) return true; - if (StringMatcher.FuzzySearch(queryString, bookmark.PinyinName).IsSearchPrecisionScoreMet()) return true; - if (StringMatcher.FuzzySearch(queryString, bookmark.Url).IsSearchPrecisionScoreMet()) return true; + var match = StringMatcher.FuzzySearch(queryString, bookmark.Name); + if (match.IsSearchPrecisionScoreMet()) + return match; - return false; + return StringMatcher.FuzzySearch(queryString, bookmark.Url); } internal static List LoadAllBookmarks() { var allbookmarks = new List(); - + var chromeBookmarks = new ChromeBookmarks(); var mozBookmarks = new FirefoxBookmarks(); var edgeBookmarks = new EdgeBookmarks(); diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarks.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarks.cs index 12b80c08a..376808549 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarks.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarks.cs @@ -18,7 +18,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark return bookmarks; } - private void ParseEdgeBookmarks(String path, string source) + private void ParseEdgeBookmarks(string path, string source) { if (!File.Exists(path)) return; @@ -72,12 +72,13 @@ namespace Flow.Launcher.Plugin.BrowserBookmark private void LoadEdgeBookmarks() { - String platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + string platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); LoadEdgeBookmarks(Path.Combine(platformPath, @"Microsoft\Edge\User Data"), "Microsoft Edge"); + LoadEdgeBookmarks(Path.Combine(platformPath, @"Microsoft\Edge Dev\User Data"), "Microsoft Edge Dev"); LoadEdgeBookmarks(Path.Combine(platformPath, @"Microsoft\Edge SxS\User Data"), "Microsoft Edge Canary"); } - private String DecodeUnicode(String dataStr) + private string DecodeUnicode(string dataStr) { Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})"); return reg.Replace(dataStr, m => ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString()); diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs index 67ee87f94..47493654f 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs @@ -12,7 +12,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, ISavable { private PluginInitContext context; - + private List cachedBookmarks = new List(); private readonly Settings _settings; @@ -37,36 +37,56 @@ namespace Flow.Launcher.Plugin.BrowserBookmark // Should top results be returned? (true if no search parameters have been passed) var topResults = string.IsNullOrEmpty(param); - - var returnList = cachedBookmarks; + if (!topResults) { // Since we mixed chrome and firefox bookmarks, we should order them again - returnList = cachedBookmarks.Where(o => Bookmarks.MatchProgram(o, param)).ToList(); - returnList = returnList.OrderByDescending(o => o.Score).ToList(); - } - - return returnList.Select(c => new Result() - { - Title = c.Name, - SubTitle = c.Url, - IcoPath = @"Images\bookmark.png", - Score = 5, - Action = (e) => + var returnList = cachedBookmarks.Select(c => new Result() { - if (_settings.OpenInNewBrowserWindow) + Title = c.Name, + SubTitle = c.Url, + IcoPath = @"Images\bookmark.png", + Score = Bookmarks.MatchProgram(c, param).Score, + Action = _ => { - c.Url.NewBrowserWindow(_settings.BrowserPath); - } - else - { - c.Url.NewTabInBrowser(_settings.BrowserPath); - } + if (_settings.OpenInNewBrowserWindow) + { + c.Url.NewBrowserWindow(_settings.BrowserPath); + } + else + { + c.Url.NewTabInBrowser(_settings.BrowserPath); + } - return true; - } - }).ToList(); + return true; + } + }).Where(r => r.Score > 0); + return returnList.ToList(); + } + else + { + return cachedBookmarks.Select(c => new Result() + { + Title = c.Name, + SubTitle = c.Url, + IcoPath = @"Images\bookmark.png", + Score = 5, + Action = _ => + { + if (_settings.OpenInNewBrowserWindow) + { + c.Url.NewBrowserWindow(_settings.BrowserPath); + } + else + { + c.Url.NewTabInBrowser(_settings.BrowserPath); + } + + return true; + } + }).ToList(); + } } public void ReloadData() diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json index 8676a3e5b..7bb662b36 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json @@ -4,7 +4,7 @@ "Name": "Browser Bookmarks", "Description": "Search your browser bookmarks", "Author": "qianlifeng, Ioannis G.", - "Version": "1.2.0", + "Version": "1.2.1", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.browserBookmark.dll", diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml index 579a64718..c266aa6f6 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml @@ -40,7 +40,12 @@ Search programs in Flow Launcher Invalid Path - + + Customized Explorer + Args + You can customized the explorer used for opening the container folder by inputing the Environmental Variable of the explorer you want to use. It will be useful to use CMD to test whether the Environmental Variable is avaliable. + Enter the customized args you want to add for your customized explorer. %s for parent directory, %f for full path (which only works for win32). Check the explorer's website for details. + Success Successfully disabled this program from displaying in your query diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs index b2520ef00..50a7cdb87 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs @@ -311,7 +311,9 @@ namespace Flow.Launcher.Plugin.Program.Programs Action = _ => { - Main.StartProcess(Process.Start, new ProcessStartInfo(Package.Location)); + Main.StartProcess(Process.Start, new ProcessStartInfo( + !string.IsNullOrEmpty(Main._settings.CustomizedExplorer) ? Main._settings.CustomizedExplorer:Settings.Explorer, + Main._settings.CustomizedArgs.Replace("%s",$"\"{Package.Location}\"").Trim())); return true; }, diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs index bf67d4798..c7dbc1ace 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs @@ -123,7 +123,20 @@ namespace Flow.Launcher.Plugin.Program.Programs Title = api.GetTranslation("flowlauncher_plugin_program_open_containing_folder"), Action = _ => { - Main.StartProcess(Process.Start, new ProcessStartInfo("explorer", ParentDirectory)); + var args = !string.IsNullOrWhiteSpace(Main._settings.CustomizedArgs) + ? Main._settings.CustomizedArgs + .Replace("%s",$"\"{ParentDirectory}\"") + .Replace("%f",$"\"{FullPath}\"") + : Main._settings.CustomizedExplorer==Settings.Explorer + ? $"/select,\"{FullPath}\"" + : Settings.ExplorerArgs; + + Main.StartProcess(Process.Start, + new ProcessStartInfo( + !string.IsNullOrWhiteSpace(Main._settings.CustomizedExplorer) + ? Main._settings.CustomizedExplorer + : Settings.Explorer, + args)); return true; }, diff --git a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs index fcb4cbf2d..7cb02a852 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs @@ -14,9 +14,15 @@ namespace Flow.Launcher.Plugin.Program public bool EnableStartMenuSource { get; set; } = true; public bool EnableRegistrySource { get; set; } = true; + public string CustomizedExplorer { get; set; } = Explorer; + public string CustomizedArgs { get; set; } = ExplorerArgs; internal const char SuffixSeperator = ';'; + internal const string Explorer = "explorer"; + + internal const string ExplorerArgs = "%s"; + /// /// Contains user added folder location contents as well as all user disabled applications /// diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml index 6051e0579..90fda1756 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml +++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml @@ -5,12 +5,13 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:program="clr-namespace:Flow.Launcher.Plugin.Program" mc:Ignorable="d" - d:DesignHeight="300" d:DesignWidth="600"> + d:DesignHeight="404.508" d:DesignWidth="600"> + @@ -24,7 +25,7 @@ - + @@ -71,9 +72,18 @@