Merge pull request #124 from Flow-Launcher/dev

Release 1.2.0 | Plugin 1.2.0
This commit is contained in:
Jeremy Wu 2020-08-17 20:07:17 +10:00 committed by GitHub
commit a8bfe6e076
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
102 changed files with 690 additions and 1686 deletions

View file

@ -29,7 +29,6 @@ namespace Flow.Launcher.Core.Plugin
else
{ // non action keyword
actionKeyword = string.Empty;
actionParameters = terms.ToList();
search = rawQuery;
}
@ -38,10 +37,7 @@ namespace Flow.Launcher.Core.Plugin
Terms = terms,
RawQuery = rawQuery,
ActionKeyword = actionKeyword,
Search = search,
// Obsolete value initialisation
ActionName = actionKeyword,
ActionParameters = actionParameters
Search = search
};
return query;

View file

@ -16,6 +16,7 @@ using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using System.IO;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core
{
@ -28,11 +29,14 @@ namespace Flow.Launcher.Core
GitHubRepository = gitHubRepository;
}
public async Task UpdateApp(bool silentIfLatestVersion = true)
public async Task UpdateApp(IPublicAPI api , bool silentUpdate = true)
{
UpdateManager updateManager;
UpdateInfo newUpdateInfo;
if (!silentUpdate)
api.ShowMsg("Please wait...", "Checking for new update");
try
{
updateManager = await GitHubUpdateManager(GitHubRepository);
@ -62,12 +66,15 @@ namespace Flow.Launcher.Core
if (newReleaseVersion <= currentVersion)
{
if (!silentIfLatestVersion)
if (!silentUpdate)
MessageBox.Show("You already have the latest Flow Launcher version");
updateManager.Dispose();
return;
}
if (!silentUpdate)
api.ShowMsg("Update found", "Updating...");
try
{
await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply);
@ -96,11 +103,15 @@ namespace Flow.Launcher.Core
var newVersionTips = NewVersinoTips(newReleaseVersion.ToString());
MessageBox.Show(newVersionTips);
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
// always dispose UpdateManager
updateManager.Dispose();
if (MessageBox.Show(newVersionTips, "New Update", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
}
[UsedImplicitly]

View file

@ -95,27 +95,6 @@ namespace Flow.Launcher.Infrastructure
private static string[] EmptyStringArray = new string[0];
private static string[][] Empty2DStringArray = new string[0][];
[Obsolete("Not accurate, eg 音乐 will not return yinyue but returns yinle ")]
/// <summary>
/// replace chinese character with pinyin, non chinese character won't be modified
/// <param name="word"> should be word or sentence, instead of single character. e.g. 微软 </param>
/// </summary>
public string[] Pinyin(string word)
{
if (!_settings.ShouldUsePinyin)
{
return EmptyStringArray;
}
var pinyin = word.Select(c =>
{
var pinyins = PinyinHelper.toHanyuPinyinStringArray(c);
var result = pinyins == null ? c.ToString() : pinyins[0];
return result;
}).ToArray();
return pinyin;
}
/// <summmary>
/// 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

View file

@ -27,7 +27,6 @@ namespace Flow.Launcher.Infrastructure
public static readonly string ErrorIcon = Path.Combine(ProgramDirectory, "Images", "app_error.png");
public static string PythonPath;
public static string EverythingSDKPath;
public static readonly string QueryTextBoxIconImagePath = $"{ProgramDirectory}\\Images\\mainsearch.png";

View file

@ -67,7 +67,6 @@ namespace Flow.Launcher.Infrastructure.Exception
sb.AppendLine($"* IntPtr Length: {IntPtr.Size}");
sb.AppendLine($"* x64: {Environment.Is64BitOperatingSystem}");
sb.AppendLine($"* Python Path: {Constant.PythonPath}");
sb.AppendLine($"* Everything SDK Path: {Constant.EverythingSDKPath}");
sb.AppendLine($"* CLR Version: {Environment.Version}");
sb.AppendLine($"* Installed .NET Framework: ");
foreach (var result in GetFrameworkVersionFromRegistry())

View file

@ -38,6 +38,7 @@
<ItemGroup>
<Compile Include="..\SolutionAssemblyInfo.cs" Link="Properties\SolutionAssemblyInfo.cs" />
<None Include="FodyWeavers.xml" />
</ItemGroup>
<ItemGroup>
@ -55,6 +56,7 @@
<PackageReference Include="Pinyin4DotNet" Version="2016.4.23.4" />
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
<PackageReference Include="PropertyChanged.Fody" Version="2.5.13" />
</ItemGroup>
<ItemGroup>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<PropertyChanged />
</Weavers>

View file

@ -1,32 +0,0 @@
using System;
namespace Flow.Launcher.Infrastructure
{
[Obsolete("This class is obsolete and should not be used. Please use the static function StringMatcher.FuzzySearch")]
public class FuzzyMatcher
{
private string query;
private MatchOption opt;
private FuzzyMatcher(string query, MatchOption opt)
{
this.query = query.Trim();
this.opt = opt;
}
public static FuzzyMatcher Create(string query)
{
return new FuzzyMatcher(query, new MatchOption());
}
public static FuzzyMatcher Create(string query, MatchOption opt)
{
return new FuzzyMatcher(query, opt);
}
public MatchResult Evaluate(string str)
{
return StringMatcher.Instance.FuzzyMatch(query, str, opt);
}
}
}

View file

@ -156,9 +156,8 @@ namespace Flow.Launcher.Infrastructure.Image
if (Directory.Exists(path))
{
/* Directories can also have thumbnails instead of shell icons.
* Generating thumbnails for a bunch of folders while scrolling through
* results from Everything makes a big impact on performance and
* Flow.Launcher responsibility.
* Generating thumbnails for a bunch of folder results while scrolling
* could have a big impact on performance and Flow.Launcher responsibility.
* - Solution: just load the icon
*/
type = ImageType.Folder;

View file

@ -21,18 +21,6 @@ namespace Flow.Launcher.Infrastructure
public static StringMatcher Instance { get; internal set; }
[Obsolete("This method is obsolete and should not be used. Please use the static function StringMatcher.FuzzySearch")]
public static int Score(string source, string target)
{
return FuzzySearch(target, source).Score;
}
[Obsolete("This method is obsolete and should not be used. Please use the static function StringMatcher.FuzzySearch")]
public static bool IsMatch(string source, string target)
{
return Score(source, target) > 0;
}
public static MatchResult FuzzySearch(string query, string stringToCompare)
{
return Instance.FuzzyMatch(query, stringToCompare);
@ -323,18 +311,6 @@ namespace Flow.Launcher.Infrastructure
public class MatchOption
{
/// <summary>
/// prefix of match char, use for highlight
/// </summary>
[Obsolete("this is never used")]
public string Prefix { get; set; } = "";
/// <summary>
/// suffix of match char, use for highlight
/// </summary>
[Obsolete("this is never used")]
public string Suffix { get; set; } = "";
public bool IgnoreCase { get; set; } = true;
}
}

View file

@ -30,5 +30,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
public static readonly string PluginsDirectory = Path.Combine(DataDirectory(), Constant.Plugins);
public static readonly string PluginSettingsDirectory = Path.Combine(DataDirectory(), "Settings", Constant.Plugins);
}
}

View file

@ -15,6 +15,16 @@ namespace Flow.Launcher.Infrastructure.UserSettings
if (Plugins.ContainsKey(metadata.ID))
{
var settings = Plugins[metadata.ID];
// TODO: Remove. This is one off for 1.2.0 release.
// Introduced a new action keyword in Explorer, so need to update plugin setting in the UserData folder.
// This kind of plugin meta update should be handled by a dedicated method trigger by version bump.
if (metadata.ID == "572be03c74c642baae319fc283e561a8" && metadata.ActionKeywords.Count != settings.ActionKeywords.Count)
settings.ActionKeywords = metadata.ActionKeywords;
if (string.IsNullOrEmpty(settings.Version))
settings.Version = metadata.Version;
if (settings.ActionKeywords?.Count > 0)
{
metadata.ActionKeywords = settings.ActionKeywords;
@ -28,6 +38,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
ID = metadata.ID,
Name = metadata.Name,
Version = metadata.Version,
ActionKeywords = metadata.ActionKeywords,
Disabled = metadata.Disabled
};
@ -39,6 +50,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
public string ID { get; set; }
public string Name { get; set; }
public string Version { get; set; }
public List<string> ActionKeywords { get; set; } // a reference of the action keywords from plugin manager
/// <summary>

View file

@ -70,12 +70,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public PluginsSettings PluginSettings { get; set; } = new PluginsSettings();
public ObservableCollection<CustomPluginHotkey> CustomPluginHotkeys { get; set; } = new ObservableCollection<CustomPluginHotkey>();
[Obsolete]
public double Opacity { get; set; } = 1;
[Obsolete]
public OpacityMode OpacityMode { get; set; } = OpacityMode.Normal;
public bool DontPromptUpdateMsg { get; set; }
public bool EnableUpdateLog { get; set; }
@ -108,12 +102,4 @@ namespace Flow.Launcher.Infrastructure.UserSettings
Empty,
Preserved
}
[Obsolete]
public enum OpacityMode
{
Normal = 0,
LayeredWindow = 1,
DWM = 2
}
}

View file

@ -11,23 +11,6 @@ namespace Flow.Launcher.Plugin
List<Result> LoadContextMenus(Result selectedResult);
}
[Obsolete("If a plugin has a action keyword, then it is exclusive. This interface will be remove in v1.3.0")]
public interface IExclusiveQuery : IFeatures
{
[Obsolete("If a plugin has a action keyword, then it is exclusive. This method will be remove in v1.3.0")]
bool IsExclusiveQuery(Query query);
}
/// <summary>
/// Represent plugin query will be executed in UI thread directly. Don't do long-running operation in Query method if you implement this interface
/// <remarks>This will improve the performance of instant search like websearch or cmd plugin</remarks>
/// </summary>
[Obsolete("Flow Launcher is fast enough now, executed on ui thread is no longer needed")]
public interface IInstantQuery : IFeatures
{
bool IsInstantQuery(string query);
}
/// <summary>
/// Represent plugins that support internationalization
/// </summary>

View file

@ -1,9 +0,0 @@
using System;
namespace Flow.Launcher.Plugin.Features
{
[Obsolete("Delete Flow.Launcher.Plugin.Features using directive, " +
"and use Flow.Launcher.Plugin.Feature.IContextMenu instead, " +
"this method will be removed in v1.3.0")]
public interface IContextMenu { }
}

View file

@ -1,9 +0,0 @@
using System;
namespace Flow.Launcher.Plugin.Features
{
[Obsolete("Delete Flow.Launcher.Plugin.Features using directive, " +
"and use Flow.Launcher.Plugin.Feature.IInstantQuery instead, " +
"this method will be removed in v1.3.0")]
public interface IExclusiveQuery { }
}

View file

@ -1,9 +0,0 @@
using System;
namespace Flow.Launcher.Plugin.Features
{
[Obsolete("Delete Flow.Launcher.Plugin.Features using directive, " +
"and use Flow.Launcher.Plugin.Feature.IInstantQuery instead, " +
"this method will be removed in v1.3.0")]
public interface IInstantQuery { }
}

View file

@ -14,10 +14,10 @@
</PropertyGroup>
<PropertyGroup>
<Version>1.1.0</Version>
<PackageVersion>1.1.0</PackageVersion>
<AssemblyVersion>1.1.0</AssemblyVersion>
<FileVersion>1.1.0</FileVersion>
<Version>1.2.0</Version>
<PackageVersion>1.2.0</PackageVersion>
<AssemblyVersion>1.2.0</AssemblyVersion>
<FileVersion>1.2.0</FileVersion>
<PackageId>Flow.Launcher.Plugin</PackageId>
<Authors>Flow-Launcher</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>

View file

@ -8,15 +8,6 @@ namespace Flow.Launcher.Plugin
/// </summary>
public interface IPublicAPI
{
/// <summary>
/// Push result to query box
/// </summary>
/// <param name="query"></param>
/// <param name="plugin"></param>
/// <param name="results"></param>
[Obsolete("This method will be removed in Flow Launcher 1.3")]
void PushResults(Query query, PluginMetadata plugin, List<Result> results);
/// <summary>
/// Change Flow.Launcher query
/// </summary>
@ -27,42 +18,11 @@ namespace Flow.Launcher.Plugin
/// </param>
void ChangeQuery(string query, bool requery = false);
/// <summary>
/// Just change the query text, this won't raise search
/// </summary>
/// <param name="query"></param>
[Obsolete]
void ChangeQueryText(string query, bool selectAll = false);
/// <summary>
/// Close Flow Launcher
/// </summary>
[Obsolete]
void CloseApp();
/// <summary>
/// Restart Flow Launcher
/// </summary>
void RestartApp();
/// <summary>
/// Restart Flow Launcher
/// </summary>
[Obsolete("Use RestartApp instead. This method will be removed in Flow Launcher 1.3")]
void RestarApp();
/// <summary>
/// Hide Flow Launcher
/// </summary>
[Obsolete]
void HideApp();
/// <summary>
/// Show Flow Launcher
/// </summary>
[Obsolete]
void ShowApp();
/// <summary>
/// Save all Flow Launcher settings
/// </summary>
@ -103,18 +63,6 @@ namespace Flow.Launcher.Plugin
/// </summary>
void OpenSettingDialog();
/// <summary>
/// Show loading animation
/// </summary>
[Obsolete("automatically start")]
void StartLoadingBar();
/// <summary>
/// Stop loading animation
/// </summary>
[Obsolete("automatically stop")]
void StopLoadingBar();
/// <summary>
/// Install Flow Launcher plugin
/// </summary>

View file

@ -43,9 +43,6 @@ namespace Flow.Launcher.Plugin
return Name;
}
[Obsolete("Use IcoPath")]
public string FullIcoPath => IcoPath;
/// <summary>
/// Init time include both plugin load time and init time
/// </summary>

View file

@ -94,14 +94,5 @@ namespace Flow.Launcher.Plugin
}
public override string ToString() => RawQuery;
[Obsolete("Use ActionKeyword, this property will be removed in v1.3.0")]
public string ActionName { get; internal set; }
[Obsolete("Use Search instead, this property will be removed in v1.3.0")]
public List<string> ActionParameters { get; internal set; }
[Obsolete("Use Search instead, this method will be removed in v1.3.0")]
public string GetAllRemainingParameter() => Search;
}
}

View file

@ -104,21 +104,6 @@ namespace Flow.Launcher.Plugin
return Title + SubTitle;
}
/// <summary>
/// Context menus associate with this result
/// </summary>
[Obsolete("Use IContextMenu instead")]
public List<Result> ContextMenu { get; set; }
[Obsolete("Use Object initializer instead")]
public Result(string Title, string IcoPath, string SubTitle = null)
{
this.Title = Title;
this.IcoPath = IcoPath;
this.SubTitle = SubTitle;
}
public Result() { }
/// <summary>

View file

@ -11,6 +11,12 @@ namespace Flow.Launcher.Plugin.SharedCommands
private const string FileExplorerProgramEXE = "explorer.exe";
/// <summary>
/// Copies the folder and all of its files and folders
/// including subfolders to the target location
/// </summary>
/// <param name="sourcePath"></param>
/// <param name="targetPath"></param>
public static void Copy(this string sourcePath, string targetPath)
{
// Get the subdirectories for the specified directory.
@ -172,7 +178,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
///<summary>
/// Gets the previous level directory from a path string.
/// Checks that previous level directory exists and returns it
/// as a path string, or empty string if doesn't exit
/// as a path string, or empty string if doesn't exist
///</summary>
public static string GetPreviousExistingDirectory(Func<string, bool> locationExists, string path)
{

View file

@ -184,6 +184,55 @@ namespace Flow.Launcher.Test.Plugins
$"Actual number of results is {results.Count} {Environment.NewLine}");
}
[TestCase(@"some words", @"FREETEXT('some words')")]
public void GivenWindowsIndexSearch_WhenQueryWhereRestrictionsIsForFileContentSearch_ThenShouldReturnFreeTextString(
string querySearchString, string expectedString)
{
// Given
var queryConstructor = new QueryConstructor(new Settings());
//When
var resultString = queryConstructor.QueryWhereRestrictionsForFileContentSearch(querySearchString);
// Then
Assert.IsTrue(resultString == expectedString,
$"Expected QueryWhereRestrictions string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {resultString}{Environment.NewLine}");
}
[TestCase("some words", "SELECT TOP 100 System.FileName, System.ItemPathDisplay, System.ItemType " +
"FROM SystemIndex WHERE FREETEXT('some words') AND scope='file:'")]
public void GivenWindowsIndexSearch_WhenSearchForFileContent_ThenQueryShouldUseExpectedString(
string userSearchString, string expectedString)
{
// Given
var queryConstructor = new QueryConstructor(new Settings());
//When
var resultString = queryConstructor.QueryForFileContentSearch(userSearchString);
// Then
Assert.IsTrue(resultString == expectedString,
$"Expected query string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {resultString}{Environment.NewLine}");
}
public void GivenQuery_WhenActionKeywordForFileContentSearchExists_ThenFileContentSearchRequiredShouldReturnTrue()
{
// Given
var query = new Query { ActionKeyword = "doc:", Search = "search term" };
var searchManager = new SearchManager(new Settings(), new PluginInitContext());
// When
var result = searchManager.IsFileContentSearch(query.ActionKeyword);
// Then
Assert.IsTrue(result,
$"Expected True for file content search. {Environment.NewLine} " +
$"Actual result was: {result}{Environment.NewLine}");
}
[TestCase(@"c:\\", false)]
[TestCase(@"i:\", true)]
[TestCase(@"\c:\", false)]

View file

@ -13,7 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{3A73
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher", "Flow.Launcher\Flow.Launcher.csproj", "{DB90F671-D861-46BB-93A3-F1304F5BA1C5}"
ProjectSection(ProjectDependencies) = postProject
{230AE83F-E92E-4E69-8355-426B305DA9C0} = {230AE83F-E92E-4E69-8355-426B305DA9C0}
{1EE20B48-82FB-48A2-8086-675D6DDAB4F0} = {1EE20B48-82FB-48A2-8086-675D6DDAB4F0}
{0B9DE348-9361-4940-ADB6-F5953BFFCCEC} = {0B9DE348-9361-4940-ADB6-F5953BFFCCEC}
{FDB3555B-58EF-4AE6-B5F1-904719637AB4} = {FDB3555B-58EF-4AE6-B5F1-904719637AB4}
@ -49,8 +48,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Url",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Color", "Plugins\Flow.Launcher.Plugin.Color\Flow.Launcher.Plugin.Color.csproj", "{F35190AA-4758-4D9E-A193-E3BDF6AD3567}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Everything", "Plugins\Flow.Launcher.Plugin.Everything\Flow.Launcher.Plugin.Everything.csproj", "{230AE83F-E92E-4E69-8355-426B305DA9C0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FFD651C7-0546-441F-BC8C-D4EE8FD01EA7}"
ProjectSection(SolutionItems) = preProject
.gitattributes = .gitattributes
@ -240,18 +237,6 @@ Global
{F35190AA-4758-4D9E-A193-E3BDF6AD3567}.Release|x64.Build.0 = Release|Any CPU
{F35190AA-4758-4D9E-A193-E3BDF6AD3567}.Release|x86.ActiveCfg = Release|Any CPU
{F35190AA-4758-4D9E-A193-E3BDF6AD3567}.Release|x86.Build.0 = Release|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Debug|x64.ActiveCfg = Debug|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Debug|x64.Build.0 = Debug|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Debug|x86.ActiveCfg = Debug|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Debug|x86.Build.0 = Debug|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Release|Any CPU.Build.0 = Release|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Release|x64.ActiveCfg = Release|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Release|x64.Build.0 = Release|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Release|x86.ActiveCfg = Release|Any CPU
{230AE83F-E92E-4E69-8355-426B305DA9C0}.Release|x86.Build.0 = Release|Any CPU
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|x64.ActiveCfg = Debug|Any CPU
@ -325,7 +310,6 @@ Global
{0B9DE348-9361-4940-ADB6-F5953BFFCCEC} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{A3DCCBCA-ACC1-421D-B16E-210896234C26} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{F35190AA-4758-4D9E-A193-E3BDF6AD3567} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{230AE83F-E92E-4E69-8355-426B305DA9C0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{9B130CC5-14FB-41FF-B310-0A95B6894C37} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{59BD9891-3837-438A-958D-ADC7F91F6F7E} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}

View file

@ -118,12 +118,12 @@ namespace Flow.Launcher
var timer = new Timer(1000 * 60 * 60 * 5);
timer.Elapsed += async (s, e) =>
{
await _updater.UpdateApp();
await _updater.UpdateApp(API);
};
timer.Start();
// check updates on startup
await _updater.UpdateApp();
await _updater.UpdateApp(API);
}
});
}

View file

@ -57,7 +57,6 @@ namespace Flow.Launcher
App.API.ChangeQuery(pluginHotkey.ActionKeyword);
Application.Current.MainWindow.Visibility = Visibility.Visible;
});
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("success"));
}
else
{
@ -76,7 +75,6 @@ namespace Flow.Launcher
App.API.ChangeQuery(updateCustomHotkey.ActionKeyword);
Application.Current.MainWindow.Visibility = Visibility.Visible;
});
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("success"));
}
Close();

View file

@ -41,8 +41,7 @@ namespace Flow.Launcher.Helper
public static string DependenciesInfo()
{
var info = $"\nPython Path: {Constant.PythonPath}" +
$"\nEverything SDK Path: {Constant.EverythingSDKPath}";
var info = $"\nPython Path: {Constant.PythonPath}";
return info;
}
}

View file

@ -96,7 +96,7 @@
<system:String x:Key="version">Version</system:String>
<system:String x:Key="about_activate_times">You have activated Flow Launcher {0} times</system:String>
<system:String x:Key="checkUpdates">Check for Updates</system:String>
<system:String x:Key="newVersionTips">New version {0} is available, please restart Flow Launcher.</system:String>
<system:String x:Key="newVersionTips">New version {0} is available, would you like to restart Flow Launcher to use the update?</system:String>
<system:String x:Key="checkUpdatesFailed">Check updates failed, please check your connection and proxy settings to api.github.com.</system:String>
<system:String x:Key="downloadUpdatesFailed">
Download updates failed, please check your connection and proxy settings to github-cloud.s3.amazonaws.com,
@ -111,7 +111,7 @@
<system:String x:Key="done">Done</system:String>
<system:String x:Key="cannotFindSpecifiedPlugin">Can't find specified plugin</system:String>
<system:String x:Key="newActionKeywordsCannotBeEmpty">New Action Keyword can't be empty</system:String>
<system:String x:Key="newActionKeywordsHasBeenAssigned">New Action Keywords have been assigned to another plugin, please assign other new action keyword</system:String>
<system:String x:Key="newActionKeywordsHasBeenAssigned">This new Action Keyword is already assigned to another plugin, please choose a different one</system:String>
<system:String x:Key="success">Success</system:String>
<system:String x:Key="actionkeyword_tips">Use * if you don't want to specify an action keyword</system:String>

View file

@ -48,12 +48,6 @@ namespace Flow.Launcher
_mainVM.ChangeQueryText(query);
}
[Obsolete]
public void CloseApp()
{
Application.Current.MainWindow.Close();
}
public void RestartApp()
{
_mainVM.MainWindowVisibility = Visibility.Hidden;
@ -90,18 +84,6 @@ namespace Flow.Launcher
PluginManager.ReloadData();
}
[Obsolete]
public void HideApp()
{
_mainVM.MainWindowVisibility = Visibility.Hidden;
}
[Obsolete]
public void ShowApp()
{
_mainVM.MainWindowVisibility = Visibility.Visible;
}
public void ShowMsg(string title, string subTitle = "", string iconPath = "")
{
ShowMsg(title, subTitle, iconPath, true);
@ -151,21 +133,6 @@ namespace Flow.Launcher
public event FlowLauncherGlobalKeyboardEventHandler GlobalKeyboardEvent;
[Obsolete("This will be removed in Flow Launcher 1.3")]
public void PushResults(Query query, PluginMetadata plugin, List<Result> results)
{
results.ForEach(o =>
{
o.PluginDirectory = plugin.PluginDirectory;
o.PluginID = plugin.ID;
o.OriginQuery = query;
});
Task.Run(() =>
{
_mainVM.UpdateResultView(results, plugin, query);
});
}
#endregion
#region Private Methods

View file

@ -248,12 +248,13 @@
<RowDefinition Height="50" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox Text="{DynamicResource hiThere}" IsReadOnly="True"
Style="{DynamicResource QueryBoxStyle}" Grid.Row="0"
<TextBox Grid.Row="0"
Text="{DynamicResource hiThere}" IsReadOnly="True"
Style="{DynamicResource QueryBoxStyle}"
Margin="18 0 56 0" />
<Image Source="{Binding ThemeImage}" HorizontalAlignment="Right" />
<ContentControl Visibility="Visible" Grid.Row="1">
<flowlauncher:ResultListBox DataContext="{Binding PreviewResults}" />
<ContentControl Grid.Row="1">
<flowlauncher:ResultListBox DataContext="{Binding PreviewResults, Mode=OneTime}" Visibility="Visible" />
</ContentControl>
</Grid>
</Border>

View file

@ -9,13 +9,10 @@
<Style x:Key="QueryBoxStyle" BasedOn="{StaticResource BaseQueryBoxStyle}" TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="#FF000000" />
<Setter Property="Background" Value="#01FFFFFF" />
<Setter Property="Background" Value="Transparent" />
</Style>
<Style x:Key="QuerySuggestionBoxStyle" BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}" TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="#FF000000" />
<Setter Property="Background" Value="#01FFFFFF" />
</Style>
<Style x:Key="QuerySuggestionBoxStyle" BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}" TargetType="{x:Type TextBox}" />
<Style x:Key="WindowBorderStyle" BasedOn="{StaticResource BaseWindowBorderStyle}" TargetType="{x:Type Border}">
<Setter Property="Background">

View file

@ -45,7 +45,7 @@ namespace Flow.Launcher.ViewModel
public async void UpdateApp()
{
await _updater.UpdateApp(false);
await _updater.UpdateApp(App.API, false);
}
public bool AutoUpdates
@ -319,36 +319,30 @@ namespace Flow.Launcher.ViewModel
{
new Result
{
Title = "WoX is a launcher for Windows that simply works.",
SubTitle = "You can call it Windows omni-eXecutor if you want a long name."
Title = "Explorer",
SubTitle = "Search for files, folders and file contents",
IcoPath = Path.Combine(Constant.ProgramDirectory, @"Plugins\Flow.Launcher.Plugin.Explorer\Images\explorer.png")
},
new Result
{
Title = "Search for everything—applications, folders, files and more.",
SubTitle = "Use pinyin to search for programs. (yyy / wangyiyun → 网易云音乐)"
Title = "WebSearch",
SubTitle = "Search the web with different search engine support",
IcoPath =Path.Combine(Constant.ProgramDirectory, @"Plugins\Flow.Launcher.Plugin.WebSearch\Images\web_search.png")
},
new Result
{
Title = "Keyword plugin search.",
SubTitle = "search google with g search_term."
Title = "Program",
SubTitle = "Launch programs as admin or a different user",
IcoPath =Path.Combine(Constant.ProgramDirectory, @"Plugins\Flow.Launcher.Plugin.Program\Images\program.png")
},
new Result
{
Title = "Build custom themes at: ",
SubTitle = Theme
},
new Result
{
Title = "Install plugins from: ",
SubTitle = Plugin
},
new Result
{
Title = $"Open Source: {_updater.GitHubRepository}",
SubTitle = "Please star it!"
Title = "ProcessKiller",
SubTitle = "Terminate unwanted processes",
IcoPath =Path.Combine(Constant.ProgramDirectory, @"Plugins\Flow.Launcher.Plugin.ProcessKiller\Images\app.png")
}
};
var vm = new ResultsViewModel();
var vm = new ResultsViewModel(Settings);
vm.AddResults(results, "PREVIEW");
return vm;
}

View file

@ -21,6 +21,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Commands
var chromeBookmarks = new ChromeBookmarks();
var mozBookmarks = new FirefoxBookmarks();
var edgeBookmarks = new EdgeBookmarks();
//TODO: Let the user select which browser's bookmarks are displayed
// Add Firefox bookmarks
@ -29,6 +30,9 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Commands
// Add Chrome bookmarks
chromeBookmarks.GetBookmarks().ForEach(x => allbookmarks.Add(x));
// Add Edge (Chromium) bookmarks
edgeBookmarks.GetBookmarks().ForEach(x => allbookmarks.Add(x));
return allbookmarks.Distinct().ToList();
}
}

View file

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace Flow.Launcher.Plugin.BrowserBookmark
{
public class EdgeBookmarks
{
private List<Bookmark> bookmarks = new List<Bookmark>();
public List<Bookmark> GetBookmarks()
{
bookmarks.Clear();
LoadEdgeBookmarks();
return bookmarks;
}
private void ParseEdgeBookmarks(String path, string source)
{
if (!File.Exists(path)) return;
string all = File.ReadAllText(path);
Regex nameRegex = new Regex("\"name\": \"(?<name>.*?)\"");
MatchCollection nameCollection = nameRegex.Matches(all);
Regex typeRegex = new Regex("\"type\": \"(?<type>.*?)\"");
MatchCollection typeCollection = typeRegex.Matches(all);
Regex urlRegex = new Regex("\"url\": \"(?<url>.*?)\"");
MatchCollection urlCollection = urlRegex.Matches(all);
List<string> names = (from Match match in nameCollection select match.Groups["name"].Value).ToList();
List<string> types = (from Match match in typeCollection select match.Groups["type"].Value).ToList();
List<string> urls = (from Match match in urlCollection select match.Groups["url"].Value).ToList();
int urlIndex = 0;
for (int i = 0; i < names.Count; i++)
{
string name = DecodeUnicode(names[i]);
string type = types[i];
if (type == "url")
{
string url = urls[urlIndex];
urlIndex++;
if (url == null) continue;
if (url.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase)) continue;
if (url.StartsWith("vbscript:", StringComparison.OrdinalIgnoreCase)) continue;
bookmarks.Add(new Bookmark()
{
Name = name,
Url = url,
Source = source
});
}
}
}
private void LoadEdgeBookmarks(string path, string name)
{
if (!Directory.Exists(path)) return;
var paths = Directory.GetDirectories(path);
foreach (var profile in paths)
{
if (File.Exists(Path.Combine(profile, "Bookmarks")))
ParseEdgeBookmarks(Path.Combine(profile, "Bookmarks"), name + (Path.GetFileName(profile) == "Default" ? "" : (" (" + Path.GetFileName(profile) + ")")));
}
}
private void LoadEdgeBookmarks()
{
String platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
LoadEdgeBookmarks(Path.Combine(platformPath, @"Microsoft\Edge\User Data"), "Microsoft Edge");
LoadEdgeBookmarks(Path.Combine(platformPath, @"Microsoft\Edge SxS\User Data"), "Microsoft Edge Canary");
}
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());
}
}
}

View file

@ -33,7 +33,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
public List<Result> Query(Query query)
{
string param = query.GetAllRemainingParameter().TrimStart();
string param = query.Search.TrimStart();
// Should top results be returned? (true if no search parameters have been passed)
var topResults = string.IsNullOrEmpty(param);

View file

@ -31,7 +31,7 @@
<StackPanel VerticalAlignment="Top" Grid.Row="1" Height="106" Margin="41,13,0,0">
<Label Content="{DynamicResource flowlauncher_plugin_browserbookmark_settings_setBrowserFromPath}"
Height="28" Margin="0,0,155,0" HorizontalAlignment="Left" Width="290"/>
<TextBox x:Name="browserPathBox" HorizontalAlignment="Left" Height="34" TextWrapping="Wrap" VerticalAlignment="Top" Width="311" RenderTransformOrigin="0.502,-1.668"/>
<TextBox x:Name="browserPathBox" HorizontalAlignment="Left" Height="34" TextWrapping="NoWrap" VerticalAlignment="Top" Width="311" RenderTransformOrigin="0.502,-1.668" TextChanged="OnBrowserPathTextChanged" />
<Button x:Name="viewButton" Content="{DynamicResource flowlauncher_plugin_browserbookmark_settings_choose}"
HorizontalAlignment="Left" Margin="340,-35,-1,0" Width="100" Height="34" Click="OnChooseClick" FontSize="14" />
</StackPanel>

View file

@ -19,7 +19,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Views
browserPathBox.Text = _settings.BrowserPath;
NewWindowBrowser.IsChecked = _settings.OpenInNewBrowserWindow;
NewTabInBrowser.IsChecked = !_settings.OpenInNewBrowserWindow;
}
}
private void OnNewBrowserWindowClick(object sender, RoutedEventArgs e)
{
@ -43,5 +43,10 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Views
_settings.BrowserPath = fileBrowserDialog.FileName;
}
}
private void OnBrowserPathTextChanged(object sender, TextChangedEventArgs e)
{
_settings.BrowserPath = browserPathBox.Text;
}
}
}

View file

@ -4,7 +4,7 @@
"Name": "Browser Bookmarks",
"Description": "Search your browser bookmarks",
"Author": "qianlifeng, Ioannis G.",
"Version": "1.1",
"Version": "1.2.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.browserBookmark.dll",

View file

@ -1,63 +0,0 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

View file

@ -1,156 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store

View file

@ -1,218 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.Everything.Everything.Exceptions;
namespace Flow.Launcher.Plugin.Everything.Everything
{
public interface IEverythingApi
{
/// <summary>
/// Searches the specified key word.
/// </summary>
/// <param name="keyWord">The key word.</param>
/// <param name="token">token that allow cancellation</param>
/// <param name="offset">The offset.</param>
/// <param name="maxCount">The max count.</param>
/// <returns></returns>
List<SearchResult> Search(string keyWord, CancellationToken token, int offset = 0, int maxCount = 100);
void Load(string sdkPath);
}
public sealed class EverythingApi : IEverythingApi
{
private const int BufferSize = 4096;
private readonly object _syncObject = new object();
// cached buffer to remove redundant allocations.
private readonly StringBuilder _buffer = new StringBuilder(BufferSize);
public enum StateCode
{
OK,
MemoryError,
IPCError,
RegisterClassExError,
CreateWindowError,
CreateThreadError,
InvalidIndexError,
InvalidCallError
}
/// <summary>
/// Gets or sets a value indicating whether [match path].
/// </summary>
/// <value><c>true</c> if [match path]; otherwise, <c>false</c>.</value>
public bool MatchPath
{
get
{
return EverythingApiDllImport.Everything_GetMatchPath();
}
set
{
EverythingApiDllImport.Everything_SetMatchPath(value);
}
}
/// <summary>
/// Gets or sets a value indicating whether [match case].
/// </summary>
/// <value><c>true</c> if [match case]; otherwise, <c>false</c>.</value>
public bool MatchCase
{
get
{
return EverythingApiDllImport.Everything_GetMatchCase();
}
set
{
EverythingApiDllImport.Everything_SetMatchCase(value);
}
}
/// <summary>
/// Gets or sets a value indicating whether [match whole word].
/// </summary>
/// <value><c>true</c> if [match whole word]; otherwise, <c>false</c>.</value>
public bool MatchWholeWord
{
get
{
return EverythingApiDllImport.Everything_GetMatchWholeWord();
}
set
{
EverythingApiDllImport.Everything_SetMatchWholeWord(value);
}
}
/// <summary>
/// Gets or sets a value indicating whether [enable regex].
/// </summary>
/// <value><c>true</c> if [enable regex]; otherwise, <c>false</c>.</value>
public bool EnableRegex
{
get
{
return EverythingApiDllImport.Everything_GetRegex();
}
set
{
EverythingApiDllImport.Everything_SetRegex(value);
}
}
/// <summary>
/// Resets this instance.
/// </summary>
public void Reset()
{
lock (_syncObject)
{
EverythingApiDllImport.Everything_Reset();
}
}
/// <summary>
/// Searches the specified key word and reset the everything API afterwards
/// </summary>
/// <param name="keyWord">The key word.</param>
/// <param name="token">when cancelled the current search will stop and exit (and would not reset)</param>
/// <param name="offset">The offset.</param>
/// <param name="maxCount">The max count.</param>
/// <returns></returns>
public List<SearchResult> Search(string keyWord, CancellationToken token, int offset = 0, int maxCount = 100)
{
if (string.IsNullOrEmpty(keyWord))
throw new ArgumentNullException(nameof(keyWord));
if (offset < 0)
throw new ArgumentOutOfRangeException(nameof(offset));
if (maxCount < 0)
throw new ArgumentOutOfRangeException(nameof(maxCount));
lock (_syncObject)
{
if (keyWord.StartsWith("@"))
{
EverythingApiDllImport.Everything_SetRegex(true);
keyWord = keyWord.Substring(1);
}
EverythingApiDllImport.Everything_SetSearchW(keyWord);
EverythingApiDllImport.Everything_SetOffset(offset);
EverythingApiDllImport.Everything_SetMax(maxCount);
if (token.IsCancellationRequested)
{
return null;
}
if (!EverythingApiDllImport.Everything_QueryW(true))
{
CheckAndThrowExceptionOnError();
return null;
}
var results = new List<SearchResult>();
for (int idx = 0; idx < EverythingApiDllImport.Everything_GetNumResults(); ++idx)
{
if (token.IsCancellationRequested)
{
return null;
}
EverythingApiDllImport.Everything_GetResultFullPathNameW(idx, _buffer, BufferSize);
var result = new SearchResult { FullPath = _buffer.ToString() };
if (EverythingApiDllImport.Everything_IsFolderResult(idx))
result.Type = ResultType.Folder;
else if (EverythingApiDllImport.Everything_IsFileResult(idx))
result.Type = ResultType.File;
results.Add(result);
}
Reset();
return results;
}
}
[DllImport("kernel32.dll")]
private static extern int LoadLibrary(string name);
public void Load(string sdkPath)
{
LoadLibrary(sdkPath);
}
private static void CheckAndThrowExceptionOnError()
{
switch (EverythingApiDllImport.Everything_GetLastError())
{
case StateCode.CreateThreadError:
throw new CreateThreadException();
case StateCode.CreateWindowError:
throw new CreateWindowException();
case StateCode.InvalidCallError:
throw new InvalidCallException();
case StateCode.InvalidIndexError:
throw new InvalidIndexException();
case StateCode.IPCError:
throw new IPCErrorException();
case StateCode.MemoryError:
throw new MemoryErrorException();
case StateCode.RegisterClassExError:
throw new RegisterClassExException();
}
}
}
}

View file

@ -1,92 +0,0 @@
using System.Runtime.InteropServices;
using System.Text;
namespace Flow.Launcher.Plugin.Everything.Everything
{
public sealed class EverythingApiDllImport
{
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
internal static extern int Everything_SetSearchW(string lpSearchString);
[DllImport(Main.DLL)]
internal static extern void Everything_SetMatchPath(bool bEnable);
[DllImport(Main.DLL)]
internal static extern void Everything_SetMatchCase(bool bEnable);
[DllImport(Main.DLL)]
internal static extern void Everything_SetMatchWholeWord(bool bEnable);
[DllImport(Main.DLL)]
internal static extern void Everything_SetRegex(bool bEnable);
[DllImport(Main.DLL)]
internal static extern void Everything_SetMax(int dwMax);
[DllImport(Main.DLL)]
internal static extern void Everything_SetOffset(int dwOffset);
[DllImport(Main.DLL)]
internal static extern bool Everything_GetMatchPath();
[DllImport(Main.DLL)]
internal static extern bool Everything_GetMatchCase();
[DllImport(Main.DLL)]
internal static extern bool Everything_GetMatchWholeWord();
[DllImport(Main.DLL)]
internal static extern bool Everything_GetRegex();
[DllImport(Main.DLL)]
internal static extern uint Everything_GetMax();
[DllImport(Main.DLL)]
internal static extern uint Everything_GetOffset();
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
internal static extern string Everything_GetSearchW();
[DllImport(Main.DLL)]
internal static extern EverythingApi.StateCode Everything_GetLastError();
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
internal static extern bool Everything_QueryW(bool bWait);
[DllImport(Main.DLL)]
internal static extern void Everything_SortResultsByPath();
[DllImport(Main.DLL)]
internal static extern int Everything_GetNumFileResults();
[DllImport(Main.DLL)]
internal static extern int Everything_GetNumFolderResults();
[DllImport(Main.DLL)]
internal static extern int Everything_GetNumResults();
[DllImport(Main.DLL)]
internal static extern int Everything_GetTotFileResults();
[DllImport(Main.DLL)]
internal static extern int Everything_GetTotFolderResults();
[DllImport(Main.DLL)]
internal static extern int Everything_GetTotResults();
[DllImport(Main.DLL)]
internal static extern bool Everything_IsVolumeResult(int nIndex);
[DllImport(Main.DLL)]
internal static extern bool Everything_IsFolderResult(int nIndex);
[DllImport(Main.DLL)]
internal static extern bool Everything_IsFileResult(int nIndex);
[DllImport(Main.DLL, CharSet = CharSet.Unicode)]
internal static extern void Everything_GetResultFullPathNameW(int nIndex, StringBuilder lpString, int nMaxCount);
[DllImport(Main.DLL)]
internal static extern void Everything_Reset();
}
}

View file

@ -1,11 +0,0 @@
using System;
namespace Flow.Launcher.Plugin.Everything.Everything
{
/// <summary>
///
/// </summary>
public class CreateThreadException : ApplicationException
{
}
}

View file

@ -1,11 +0,0 @@
using System;
namespace Flow.Launcher.Plugin.Everything.Everything
{
/// <summary>
///
/// </summary>
public class CreateWindowException : ApplicationException
{
}
}

View file

@ -1,11 +0,0 @@
using System;
namespace Flow.Launcher.Plugin.Everything.Everything
{
/// <summary>
///
/// </summary>
public class IPCErrorException : ApplicationException
{
}
}

View file

@ -1,11 +0,0 @@
using System;
namespace Flow.Launcher.Plugin.Everything.Everything
{
/// <summary>
///
/// </summary>
public class InvalidCallException : ApplicationException
{
}
}

View file

@ -1,11 +0,0 @@
using System;
namespace Flow.Launcher.Plugin.Everything.Everything
{
/// <summary>
///
/// </summary>
public class InvalidIndexException : ApplicationException
{
}
}

View file

@ -1,11 +0,0 @@
using System;
namespace Flow.Launcher.Plugin.Everything.Everything.Exceptions
{
/// <summary>
///
/// </summary>
public class MemoryErrorException : ApplicationException
{
}
}

View file

@ -1,11 +0,0 @@
using System;
namespace Flow.Launcher.Plugin.Everything.Everything
{
/// <summary>
///
/// </summary>
public class RegisterClassExException : ApplicationException
{
}
}

View file

@ -1,9 +0,0 @@
namespace Flow.Launcher.Plugin.Everything.Everything
{
public enum ResultType
{
Volume,
Folder,
File
}
}

View file

@ -1,8 +0,0 @@
namespace Flow.Launcher.Plugin.Everything.Everything
{
public class SearchResult
{
public string FullPath { get; set; }
public ResultType Type { get; set; }
}
}

View file

@ -1,28 +0,0 @@
<UserControl x:Class="Flow.Launcher.Plugin.Everything.EverythingSettings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Loaded="View_Loaded"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Margin="7,50" VerticalAlignment="Top" >
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<CheckBox Grid.Row="0" Grid.ColumnSpan="3" x:Name="UseLocationAsWorkingDir" Content="{DynamicResource
flowlauncher_plugin_everything_use_location_as_working_dir}"
Margin="10" HorizontalAlignment="Left" />
<Label Grid.Row="1" Margin="10" Content="{DynamicResource flowlauncher_plugin_everything_editor_path}"
HorizontalAlignment="Left"/>
<Label Grid.Row="1" Grid.Column="1" x:Name="EditorPath" Margin="10" HorizontalAlignment="Left" />
<Button Grid.Row="1" Grid.Column="2" x:Name="OpenEditorPath" Content="..." Margin="10"
HorizontalAlignment="Left" Click="EditorPath_Clicked"/>
</Grid>
</UserControl>

View file

@ -1,49 +0,0 @@
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
namespace Flow.Launcher.Plugin.Everything
{
public partial class EverythingSettings : UserControl
{
private readonly Settings _settings;
public EverythingSettings(Settings settings)
{
InitializeComponent();
_settings = settings;
}
private void View_Loaded(object sender, RoutedEventArgs re)
{
UseLocationAsWorkingDir.IsChecked = _settings.UseLocationAsWorkingDir;
UseLocationAsWorkingDir.Checked += (o, e) =>
{
_settings.UseLocationAsWorkingDir = true;
};
UseLocationAsWorkingDir.Unchecked += (o, e) =>
{
_settings.UseLocationAsWorkingDir = false;
};
EditorPath.Content = _settings.EditorPath;
}
private void EditorPath_Clicked(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Executable File(*.exe)| *.exe";
if (!string.IsNullOrEmpty(_settings.EditorPath))
openFileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(_settings.EditorPath);
if (openFileDialog.ShowDialog() == true)
{
_settings.EditorPath = openFileDialog.FileName;
}
EditorPath.Content = _settings.EditorPath;
}
}
}

View file

@ -1,131 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{230AE83F-E92E-4E69-8355-426B305DA9C0}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Flow.Launcher.Plugin.Everything</RootNamespace>
<AssemblyName>Flow.Launcher.Plugin.Everything</AssemblyName>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Flow.Launcher.Plugin.Everything\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Output\Release\Plugins\Flow.Launcher.Plugin.Everything\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Content Include="EverythingSDK\x64\Everything.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="EverythingSDK\x86\Everything.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\error.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\file.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\find.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\folder.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\image.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\warning.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Flow.Launcher.Infrastructure\Flow.Launcher.Infrastructure.csproj" />
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="Languages\en.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Languages\zh-cn.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Languages\zh-tw.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Languages\de.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Languages\pl.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Page Include="EverythingSettings.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Content Include="Languages\tr.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
</ItemGroup>
</Project>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 B

View file

@ -1,18 +0,0 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="flowlauncher_plugin_everything_is_not_running">Everything Service läuft nicht</system:String>
<system:String x:Key="flowlauncher_plugin_everything_query_error">Everything Plugin hat einen Fehler (drücke Enter zum kopieren der Fehlernachricht)</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copied">kopiert</system:String>
<system:String x:Key="flowlauncher_plugin_everything_canot_start">Kann {0} nicht starten</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_containing_folder">Öffne enthaltenden Ordner</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_with_editor">Openen met {0}</system:String>
<system:String x:Key="flowlauncher_plugin_everything_editor_path">Editor pad</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_name">Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_description">Suche Dateien mit Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_use_location_as_working_dir">Verwenden Suchergebnis Standort als ausführbare Arbeitsverzeichnis</system:String>
</ResourceDictionary>

View file

@ -1,22 +0,0 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="flowlauncher_plugin_everything_is_not_running">Everything Service is not running</system:String>
<system:String x:Key="flowlauncher_plugin_everything_query_error">Error while querying Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copied">Copied</system:String>
<system:String x:Key="flowlauncher_plugin_everything_canot_start">Cant start {0}</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_containing_folder">Open parent folder</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_with_editor">Open with {0}</system:String>
<system:String x:Key="flowlauncher_plugin_everything_editor_path">Editor Path</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copy_path">Copy path</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copy">Copy</system:String>
<system:String x:Key="flowlauncher_plugin_everything_delete">Delete</system:String>
<system:String x:Key="flowlauncher_plugin_everything_canot_delete">Can't delete {0}</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_name">Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_description">Search on-disk files using Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_use_location_as_working_dir">Use search result's location as executable working directory</system:String>
</ResourceDictionary>

View file

@ -1,16 +0,0 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="flowlauncher_plugin_everything_is_not_running">Everything Service nie jest uruchomiony</system:String>
<system:String x:Key="flowlauncher_plugin_everything_query_error">Wystąpił błąd podczas pobierania wyników z Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copied">Skopiowano</system:String>
<system:String x:Key="flowlauncher_plugin_everything_canot_start">Nie udało się uruchomić {0}</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_containing_folder">Otwórz folder nadrzędny.</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_with_editor">Otwórz za pomocą {0}</system:String>
<system:String x:Key="flowlauncher_plugin_everything_editor_path">Ścieżka edytora</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_name">Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_description">Szukaj w plikach na dysku używając programu Everything</system:String>
</ResourceDictionary>

View file

@ -1,22 +0,0 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="flowlauncher_plugin_everything_is_not_running">Everything Servisi çalışmıyor</system:String>
<system:String x:Key="flowlauncher_plugin_everything_query_error">Sorgu Everything üzerinde çalıştırılırken hata oluştu</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copied">Kopyalandı</system:String>
<system:String x:Key="flowlauncher_plugin_everything_canot_start">{0} başlatılamıyor</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_containing_folder">İçeren klasörü aç</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_with_editor">{0} ile aç</system:String>
<system:String x:Key="flowlauncher_plugin_everything_editor_path">Düzenleyici Konumu</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copy_path">Konumu Kopyala</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copy">Kopyala</system:String>
<system:String x:Key="flowlauncher_plugin_everything_delete">Sil</system:String>
<system:String x:Key="flowlauncher_plugin_everything_canot_delete">{0} silinemiyor</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_name">Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_description">Everything programı yardımıyla diskteki dosyalarınızı arayın.</system:String>
<system:String x:Key="flowlauncher_plugin_everything_use_location_as_working_dir">Programın çalışma klasörü olarak sonuç klasörünü kullan</system:String>
</ResourceDictionary>

View file

@ -1,21 +0,0 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="flowlauncher_plugin_everything_is_not_running">Everything Service 没有运行</system:String>
<system:String x:Key="flowlauncher_plugin_everything_query_error">Everything 插件发生了一个错误(回车拷贝具体错误信息)</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copied">拷贝成功</system:String>
<system:String x:Key="flowlauncher_plugin_everything_canot_start">不能启动 {0}</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_containing_folder">打开所属文件夹</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_with_editor">使用{0}打开</system:String>
<system:String x:Key="flowlauncher_plugin_everything_editor_path">编辑器路径</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copy_path">拷贝路径</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copy">拷贝</system:String>
<system:String x:Key="flowlauncher_plugin_everything_delete">删除</system:String>
<system:String x:Key="flowlauncher_plugin_everything_canot_delete">无法删除 {0}</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_name">Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_description">利用 Everything 搜索磁盘文件</system:String>
<system:String x:Key="flowlauncher_plugin_everything_use_location_as_working_dir">使用应用程序的位置为可执行的工作目录</system:String>
</ResourceDictionary>

View file

@ -1,17 +0,0 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="flowlauncher_plugin_everything_is_not_running">Everything Service 尚未啟動</system:String>
<system:String x:Key="flowlauncher_plugin_everything_query_error">Everything 套件發生錯誤Enter 複製具體錯誤訊息)</system:String>
<system:String x:Key="flowlauncher_plugin_everything_copied">複製成功</system:String>
<system:String x:Key="flowlauncher_plugin_everything_canot_start">無法啟動 {0}</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_containing_folder">開啟檔案位置</system:String>
<system:String x:Key="flowlauncher_plugin_everything_open_with_editor">利用{0}啟動</system:String>
<system:String x:Key="flowlauncher_plugin_everything_editor_path">編輯器路径</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_name">Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_plugin_description">利用 Everything 搜尋磁碟上的檔案</system:String>
<system:String x:Key="flowlauncher_plugin_everything_use_location_as_working_dir">使用程式所在目錄作為工作目錄</system:String>
</ResourceDictionary>

View file

@ -1,286 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin.Everything.Everything;
namespace Flow.Launcher.Plugin.Everything
{
public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu, ISavable
{
public const string DLL = "Everything.dll";
private readonly IEverythingApi _api = new EverythingApi();
private PluginInitContext _context;
private Settings _settings;
private PluginJsonStorage<Settings> _storage;
private CancellationTokenSource _cancellationTokenSource;
public void Save()
{
_storage.Save();
}
public List<Result> Query(Query query)
{
_cancellationTokenSource?.Cancel(); // cancel if already exist
var cts = _cancellationTokenSource = new CancellationTokenSource();
var results = new List<Result>();
if (!string.IsNullOrEmpty(query.Search))
{
var keyword = query.Search;
try
{
var searchList = _api.Search(keyword, cts.Token, maxCount: _settings.MaxSearchCount);
if (searchList == null)
{
return results;
}
foreach (var searchResult in searchList)
{
var r = CreateResult(keyword, searchResult);
results.Add(r);
}
}
catch (IPCErrorException)
{
results.Add(new Result
{
Title = _context.API.GetTranslation("flowlauncher_plugin_everything_is_not_running"),
IcoPath = "Images\\warning.png"
});
}
catch (Exception e)
{
Log.Exception("EverythingPlugin", "Query Error", e);
results.Add(new Result
{
Title = _context.API.GetTranslation("flowlauncher_plugin_everything_query_error"),
SubTitle = e.Message,
Action = _ =>
{
Clipboard.SetText(e.Message + "\r\n" + e.StackTrace);
_context.API.ShowMsg(_context.API.GetTranslation("flowlauncher_plugin_everything_copied"), null, string.Empty);
return false;
},
IcoPath = "Images\\error.png"
});
}
}
return results;
}
private Result CreateResult(string keyword, SearchResult searchResult)
{
var path = searchResult.FullPath;
string workingDir = null;
if (_settings.UseLocationAsWorkingDir)
workingDir = Path.GetDirectoryName(path);
var r = new Result
{
Title = Path.GetFileName(path),
SubTitle = path,
IcoPath = path,
TitleHighlightData = StringMatcher.FuzzySearch(keyword, Path.GetFileName(path)).MatchData,
Action = c =>
{
bool hide;
try
{
Process.Start(new ProcessStartInfo
{
FileName = path, UseShellExecute = true, WorkingDirectory = workingDir
});
hide = true;
}
catch (Win32Exception)
{
var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
var message = "Can't open this file";
_context.API.ShowMsg(name, message, string.Empty);
hide = false;
}
return hide;
},
ContextData = searchResult,
SubTitleHighlightData = StringMatcher.FuzzySearch(keyword, path).MatchData
};
return r;
}
private List<ContextMenu> GetDefaultContextMenu()
{
List<ContextMenu> defaultContextMenus = new List<ContextMenu>();
ContextMenu openFolderContextMenu = new ContextMenu
{
Name = _context.API.GetTranslation("flowlauncher_plugin_everything_open_containing_folder"),
Command = "explorer.exe",
Argument = " /select,\"{path}\"",
ImagePath = "Images\\folder.png"
};
defaultContextMenus.Add(openFolderContextMenu);
string editorPath = string.IsNullOrEmpty(_settings.EditorPath) ? "notepad.exe" : _settings.EditorPath;
ContextMenu openWithEditorContextMenu = new ContextMenu
{
Name = string.Format(_context.API.GetTranslation("flowlauncher_plugin_everything_open_with_editor"), Path.GetFileNameWithoutExtension(editorPath)),
Command = editorPath,
Argument = " \"{path}\"",
ImagePath = editorPath
};
defaultContextMenus.Add(openWithEditorContextMenu);
return defaultContextMenus;
}
public void Init(PluginInitContext context)
{
_context = context;
_storage = new PluginJsonStorage<Settings>();
_settings = _storage.Load();
if (_settings.MaxSearchCount <= 0)
{
_settings.MaxSearchCount = Settings.DefaultMaxSearchCount;
}
var pluginDirectory = context.CurrentPluginMetadata.PluginDirectory;
const string sdk = "EverythingSDK";
var bundledSDKDirectory = Path.Combine(pluginDirectory, sdk, CpuType());
var sdkDirectory = Path.Combine(_storage.DirectoryPath, sdk, CpuType());
Helper.ValidateDataDirectory(bundledSDKDirectory, sdkDirectory);
var sdkPath = Path.Combine(sdkDirectory, DLL);
Constant.EverythingSDKPath = sdkPath;
_api.Load(sdkPath);
}
private static string CpuType()
{
return Environment.Is64BitOperatingSystem ? "x64" : "x86";
}
public string GetTranslatedPluginTitle()
{
return _context.API.GetTranslation("flowlauncher_plugin_everything_plugin_name");
}
public string GetTranslatedPluginDescription()
{
return _context.API.GetTranslation("flowlauncher_plugin_everything_plugin_description");
}
public List<Result> LoadContextMenus(Result selectedResult)
{
SearchResult record = selectedResult.ContextData as SearchResult;
List<Result> contextMenus = new List<Result>();
if (record == null) return contextMenus;
List<ContextMenu> availableContextMenus = new List<ContextMenu>();
availableContextMenus.AddRange(GetDefaultContextMenu());
availableContextMenus.AddRange(_settings.ContextMenus);
if (record.Type == ResultType.File)
{
foreach (ContextMenu contextMenu in availableContextMenus)
{
var menu = contextMenu;
contextMenus.Add(new Result
{
Title = contextMenu.Name,
Action = _ =>
{
string argument = menu.Argument.Replace("{path}", record.FullPath);
try
{
Process.Start(menu.Command, argument);
}
catch
{
_context.API.ShowMsg(string.Format(_context.API.GetTranslation("flowlauncher_plugin_everything_canot_start"), record.FullPath), string.Empty, string.Empty);
return false;
}
return true;
},
IcoPath = contextMenu.ImagePath
});
}
}
var icoPath = (record.Type == ResultType.File) ? "Images\\file.png" : "Images\\folder.png";
contextMenus.Add(new Result
{
Title = _context.API.GetTranslation("flowlauncher_plugin_everything_copy_path"),
Action = (context) =>
{
Clipboard.SetText(record.FullPath);
return true;
},
IcoPath = icoPath
});
contextMenus.Add(new Result
{
Title = _context.API.GetTranslation("flowlauncher_plugin_everything_copy"),
Action = (context) =>
{
Clipboard.SetFileDropList(new System.Collections.Specialized.StringCollection { record.FullPath });
return true;
},
IcoPath = icoPath
});
if (record.Type == ResultType.File || record.Type == ResultType.Folder)
contextMenus.Add(new Result
{
Title = _context.API.GetTranslation("flowlauncher_plugin_everything_delete"),
Action = (context) =>
{
try
{
if (record.Type == ResultType.File)
System.IO.File.Delete(record.FullPath);
else
System.IO.Directory.Delete(record.FullPath);
}
catch
{
_context.API.ShowMsg(string.Format(_context.API.GetTranslation("flowlauncher_plugin_everything_canot_delete"), record.FullPath), string.Empty, string.Empty);
return false;
}
return true;
},
IcoPath = icoPath
});
return contextMenus;
}
public Control CreateSettingPanel()
{
return new EverythingSettings(_settings);
}
}
}

View file

@ -1,4 +0,0 @@
Flow.Launcher.Plugin.Everything
=====================
Flow.Launcher plugin for Everything

View file

@ -1,28 +0,0 @@
using System.Collections.Generic;
using System.ComponentModel;
using Newtonsoft.Json;
using Flow.Launcher.Infrastructure.Storage;
namespace Flow.Launcher.Plugin.Everything
{
public class Settings
{
public const int DefaultMaxSearchCount = 50;
public string EditorPath { get; set; } = "";
public List<ContextMenu> ContextMenus = new List<ContextMenu>();
public int MaxSearchCount { get; set; } = DefaultMaxSearchCount;
public bool UseLocationAsWorkingDir { get; set; } = false;
}
public class ContextMenu
{
public string Name { get; set; }
public string Command { get; set; }
public string Argument { get; set; }
public string ImagePath { get; set; }
}
}

View file

@ -1,13 +0,0 @@
{
"ID": "D2D2C23B084D411DB66FE0C79D6C2A6E",
"ActionKeyword": "*",
"Name": "Everything",
"Description": "Search Everything",
"Author": "qianlifeng,orzfly",
"Version": "1.1.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"IcoPath": "Images\\find.png",
"ExecuteFileName": "Flow.Launcher.Plugin.Everything.dll",
"Disabled": true
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@ -9,7 +9,10 @@ using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.FolderLinks;
using System.Linq;
using System.Reflection;
using MessageBox = System.Windows.Forms.MessageBox;
using MessageBoxIcon = System.Windows.Forms.MessageBoxIcon;
using MessageBoxButton = System.Windows.Forms.MessageBoxButtons;
using DialogResult = System.Windows.Forms.DialogResult;
namespace Flow.Launcher.Plugin.Explorer
{
@ -101,10 +104,25 @@ namespace Flow.Launcher.Plugin.Explorer
{
try
{
if (MessageBox.Show(
string.Format(Context.API.GetTranslation("plugin_explorer_deletefilefolderconfirm"),fileOrFolder),
string.Empty,
MessageBoxButton.YesNo,
MessageBoxIcon.Warning)
== DialogResult.No)
return false;
if (record.Type == ResultType.File)
File.Delete(record.FullPath);
else
Directory.Delete(record.FullPath, true);
Task.Run(() =>
{
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_deletefilefoldersuccess"),
string.Format(Context.API.GetTranslation("plugin_explorer_deletefilefoldersuccess_detail"), fileOrFolder),
Constants.ExplorerIconImageFullPath);
});
}
catch (Exception e)
{
@ -212,15 +230,11 @@ namespace Flow.Launcher.Plugin.Explorer
if(!Settings.IndexSearchExcludedSubdirectoryPaths.Any(x => x.Path == record.FullPath))
Settings.IndexSearchExcludedSubdirectoryPaths.Add(new FolderLink { Path = record.FullPath });
var pluginDirectory = Directory.GetParent(Assembly.GetExecutingAssembly().Location.ToString());
var iconPath = pluginDirectory + "\\" + Constants.ExplorerIconImagePath;
Task.Run(() =>
{
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_excludedfromindexsearch_msg"),
Context.API.GetTranslation("plugin_explorer_path") +
" " + record.FullPath, iconPath);
" " + record.FullPath, Constants.ExplorerIconImageFullPath);
// so the new path can be persisted to storage and not wait till next ViewModel save.
Context.API.SaveAppAllSettings();

View file

@ -104,6 +104,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Flow.Launcher.Core\Flow.Launcher.Core.csproj" />
<ProjectReference Include="..\..\Flow.Launcher.Infrastructure\Flow.Launcher.Infrastructure.csproj" />
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
</ItemGroup>

View file

@ -1,19 +1,25 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<!--Dialogues-->
<system:String x:Key="plugin_explorer_make_selection_warning">Please make a selection first</system:String>
<system:String x:Key="plugin_explorer_select_folder_link_warning">Please select a folder link</system:String>
<system:String x:Key="plugin_explorer_delete_folder_link">Are you sure you want to delete {0}?</system:String>
<system:String x:Key="plugin_explorer_deletefilefolderconfirm">Are you sure you want to permanently delete this {0}?</system:String>
<system:String x:Key="plugin_explorer_deletefilefoldersuccess">Deletion successful</system:String>
<system:String x:Key="plugin_explorer_deletefilefoldersuccess_detail">Successfully deleted the {0}</system:String>
<!--Controls-->
<system:String x:Key="plugin_explorer_delete">Delete</system:String>
<system:String x:Key="plugin_explorer_edit">Edit</system:String>
<system:String x:Key="plugin_explorer_add">Add</system:String>
<system:String x:Key="plugin_explorer_manageactionkeywords_header">Customise Action Keywords</system:String>
<system:String x:Key="plugin_explorer_quickfolderaccess_header">Quick Folder Access Paths</system:String>
<system:String x:Key="plugin_explorer_indexsearchexcludedpaths_header">Index Search Excluded Paths</system:String>
<system:String x:Key="plugin_explorer_manageindexoptions">Indexing Options</system:String>
<system:String x:Key="plugin_explorer_actionkeywordview_search">Search Activation:</system:String>
<system:String x:Key="plugin_explorer_actionkeywordview_filecontentsearch">File Content Search:</system:String>
<!--Plugin Infos-->
<system:String x:Key="plugin_explorer_plugin_name">Explorer</system:String>

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
namespace Flow.Launcher.Plugin.Explorer.Search
{
@ -25,5 +25,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search
internal const char DirectorySeperator = '\\';
internal const string WindowsIndexingOptions = "srchadmin.dll";
internal static string ExplorerIconImageFullPath
=> Directory.GetParent(Assembly.GetExecutingAssembly().Location.ToString()) + "\\" + ExplorerIconImagePath;
}
}

View file

@ -36,12 +36,15 @@ namespace Flow.Launcher.Plugin.Explorer.Search
var quickFolderLinks = quickFolderAccess.FolderList(query, settings.QuickFolderAccessLinks, context);
if (quickFolderLinks.Count > 0)
if (quickFolderLinks.Count > 0 && query.ActionKeyword == settings.SearchActionKeyword)
return quickFolderLinks;
if (string.IsNullOrEmpty(querySearch))
return results;
if (IsFileContentSearch(query.ActionKeyword))
return WindowsIndexFileContentSearch(query, querySearch);
var isEnvironmentVariable = EnvironmentVariables.IsEnvironmentVariableSearch(querySearch);
if (isEnvironmentVariable)
@ -74,6 +77,24 @@ namespace Flow.Launcher.Plugin.Explorer.Search
return results;
}
private List<Result> WindowsIndexFileContentSearch(Query query, string querySearchString)
{
var queryConstructor = new QueryConstructor(settings);
if (string.IsNullOrEmpty(querySearchString))
return new List<Result>();
return indexSearch.WindowsIndexSearch(querySearchString,
queryConstructor.CreateQueryHelper().ConnectionString,
queryConstructor.QueryForFileContentSearch,
query);
}
public bool IsFileContentSearch(string actionKeyword)
{
return actionKeyword == settings.FileContentSearchActionKeyword;
}
private List<Result> DirectoryInfoClassSearch(Query query, string querySearch)
{
var directoryInfoSearch = new DirectoryInfoSearch(context);

View file

@ -117,5 +117,23 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
{
return $"scope='file:'";
}
///<summary>
/// Search will be performed on all indexed file contents for the specified search keywords.
///</summary>
public string QueryForFileContentSearch(string userSearchString)
{
string query = "SELECT TOP " + settings.MaxResult + $" {CreateBaseQuery().QuerySelectColumns} FROM {SystemIndex} WHERE ";
return query + QueryWhereRestrictionsForFileContentSearch(userSearchString) + " AND " + QueryWhereRestrictionsForAllFilesAndFoldersSearch();
}
///<summary>
/// Set the required WHERE clause restriction to search within file content.
///</summary>
public string QueryWhereRestrictionsForFileContentSearch(string searchQuery)
{
return $"FREETEXT('{searchQuery}')";
}
}
}

View file

@ -17,5 +17,11 @@ namespace Flow.Launcher.Plugin.Explorer
[JsonProperty]
public List<FolderLink> IndexSearchExcludedSubdirectoryPaths { get; set; } = new List<FolderLink>();
[JsonProperty]
public string SearchActionKeyword { get; set; } = Query.GlobalPluginWildcardSign;
[JsonProperty]
public string FileContentSearchActionKeyword { get; set; } = "doc:";
}
}

View file

@ -1,4 +1,5 @@
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.FolderLinks;
using System.Diagnostics;
@ -40,5 +41,18 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
Process.Start(psi);
}
internal void UpdateActionKeyword(string newActionKeyword, string oldActionKeyword)
{
PluginManager.ReplaceActionKeyword(Context.CurrentPluginMetadata.ID, oldActionKeyword, newActionKeyword);
if (Settings.FileContentSearchActionKeyword == oldActionKeyword)
Settings.FileContentSearchActionKeyword = newActionKeyword;
if (Settings.SearchActionKeyword == oldActionKeyword)
Settings.SearchActionKeyword = newActionKeyword;
}
internal bool IsActionKeywordAlreadyAssigned(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
}
}

View file

@ -0,0 +1,36 @@
<Window x:Class="Flow.Launcher.Plugin.Explorer.Views.ActionKeywordSetting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Flow.Launcher.Plugin.Explorer.Views"
mc:Ignorable="d"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen"
Title="Action Keyword Setting" Height="200" Width="500">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Margin="20 10 10 10" FontSize="14" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center"
HorizontalAlignment="Left" Text="Current Action Keyword:" />
<TextBox Name="txtCurrentActionKeyword"
Margin="10" Grid.Row="0" Width="105" Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="1" Grid.Column="1">
<Button Click="OnConfirmButtonClick"
Margin="10 0 10 0" Width="80" Height="35"
Content="OK" />
<Button Click="OnCancelButtonClick"
Margin="10 0 10 0" Width="80" Height="35"
Content="Cancel" />
</StackPanel>
</Grid>
</Window>

View file

@ -0,0 +1,76 @@
using Flow.Launcher.Plugin.Explorer.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Flow.Launcher.Plugin.Explorer.Views
{
/// <summary>
/// Interaction logic for ActionKeywordSetting.xaml
/// </summary>
public partial class ActionKeywordSetting : Window
{
private SettingsViewModel settingsViewModel;
private ActionKeywordView currentActionKeyword;
private List<ActionKeywordView> actionKeywordListView;
public ActionKeywordSetting(SettingsViewModel settingsViewModel, List<ActionKeywordView> actionKeywordListView, ActionKeywordView selectedActionKeyword)
{
InitializeComponent();
this.settingsViewModel = settingsViewModel;
currentActionKeyword = selectedActionKeyword;
txtCurrentActionKeyword.Text = selectedActionKeyword.Keyword;
this.actionKeywordListView = actionKeywordListView;
}
private void OnConfirmButtonClick(object sender, RoutedEventArgs e)
{
var newActionKeyword = txtCurrentActionKeyword.Text;
if (string.IsNullOrEmpty(newActionKeyword))
return;
if (newActionKeyword == currentActionKeyword.Keyword)
{
Close();
return;
}
if(!settingsViewModel.IsActionKeywordAlreadyAssigned(newActionKeyword))
{
settingsViewModel.UpdateActionKeyword(newActionKeyword, currentActionKeyword.Keyword);
actionKeywordListView.Where(x => x.Description == currentActionKeyword.Description).FirstOrDefault().Keyword = newActionKeyword;
Close();
return;
}
MessageBox.Show(settingsViewModel.Context.API.GetTranslation("newActionKeywordsHasBeenAssigned"));
}
private void OnCancelButtonClick(object sender, RoutedEventArgs e)
{
Close();
return;
}
}
}

View file

@ -1,4 +1,4 @@
<UserControl x:Class="Flow.Launcher.Plugin.Explorer.Views.ExplorerSettings"
<UserControl x:Class="Flow.Launcher.Plugin.Explorer.Views.ExplorerSettings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@ -17,6 +17,16 @@
Text="{Binding Nickname, Mode=OneTime}"
Margin="0,5,0,5" />
</DataTemplate>
<DataTemplate x:Key="ListViewActionKeywords">
<Grid>
<TextBlock
Text="{Binding Description, Mode=OneTime}"
Margin="0,5,0,0" />
<TextBlock
Text="{Binding Keyword, Mode=OneTime}"
Margin="150,5,0,0" />
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
@ -25,8 +35,14 @@
</Grid.RowDefinitions>
<ScrollViewer Margin="20 35 0 0" HorizontalScrollBarVisibility="Hidden" Grid.Row="0" VerticalScrollBarVisibility="Auto">
<StackPanel>
<Expander Name="expActionKeywords" Header="{DynamicResource plugin_explorer_manageactionkeywords_header}"
Expanded="expActionKeywords_Click" Collapsed="expActionKeywords_Collapsed">
<ListView x:Name="lbxActionKeywords"
ItemTemplate="{StaticResource ListViewActionKeywords}"/>
</Expander>
<Expander Name="expFolderLinks" Header="{DynamicResource plugin_explorer_quickfolderaccess_header}"
Expanded="expFolderLinks_Click" Collapsed="expFolderLinks_Click">
Expanded="expFolderLinks_Click" Collapsed="expFolderLinks_Collapsed"
Margin="0 10 0 0">
<ListView
x:Name="lbxFolderLinks" AllowDrop="True"
Drop="lbxFolders_Drop"
@ -34,7 +50,7 @@
ItemTemplate="{StaticResource ListViewTemplateFolderLinks}"/>
</Expander>
<Expander x:Name="expExcludedPaths" Header="{DynamicResource plugin_explorer_indexsearchexcludedpaths_header}"
Expanded="expExcludedPaths_Click" Collapsed="expExcludedPaths_Click"
Expanded="expExcludedPaths_Click"
Margin="0 10 0 0">
<ListView
x:Name="lbxExcludedPaths" AllowDrop="True"

View file

@ -20,6 +20,9 @@ namespace Flow.Launcher.Plugin.Explorer.Views
public partial class ExplorerSettings
{
private readonly SettingsViewModel viewModel;
private List<ActionKeywordView> actionKeywordsListView;
public ExplorerSettings(SettingsViewModel viewModel)
{
InitializeComponent();
@ -30,6 +33,22 @@ namespace Flow.Launcher.Plugin.Explorer.Views
lbxExcludedPaths.ItemsSource = this.viewModel.Settings.IndexSearchExcludedSubdirectoryPaths;
actionKeywordsListView = new List<ActionKeywordView>
{
new ActionKeywordView()
{
Description = viewModel.Context.API.GetTranslation("plugin_explorer_actionkeywordview_search"),
Keyword = this.viewModel.Settings.SearchActionKeyword
},
new ActionKeywordView()
{
Description = viewModel.Context.API.GetTranslation("plugin_explorer_actionkeywordview_filecontentsearch"),
Keyword = this.viewModel.Settings.FileContentSearchActionKeyword
}
};
lbxActionKeywords.ItemsSource = actionKeywordsListView;
RefreshView();
}
@ -43,9 +62,14 @@ namespace Flow.Launcher.Plugin.Explorer.Views
btnEdit.Visibility = Visibility.Hidden;
btnAdd.Visibility = Visibility.Hidden;
if (expFolderLinks.IsExpanded || expExcludedPaths.IsExpanded)
if (expFolderLinks.IsExpanded || expExcludedPaths.IsExpanded || expActionKeywords.IsExpanded)
{
btnAdd.Visibility = Visibility.Visible;
if (!expActionKeywords.IsExpanded)
btnAdd.Visibility = Visibility.Visible;
if (expActionKeywords.IsExpanded
&& btnEdit.Visibility == Visibility.Hidden)
btnEdit.Visibility = Visibility.Visible;
if ((lbxFolderLinks.Items.Count == 0 && lbxExcludedPaths.Items.Count == 0)
&& btnDelete.Visibility == Visibility.Visible
@ -77,22 +101,50 @@ namespace Flow.Launcher.Plugin.Explorer.Views
lbxFolderLinks.Items.Refresh();
lbxExcludedPaths.Items.Refresh();
lbxActionKeywords.Items.Refresh();
}
private void expActionKeywords_Click(object sender, RoutedEventArgs e)
{
if (expActionKeywords.IsExpanded)
expActionKeywords.Height = 215;
if (expExcludedPaths.IsExpanded)
expExcludedPaths.IsExpanded = false;
if (expFolderLinks.IsExpanded)
expFolderLinks.IsExpanded = false;
RefreshView();
}
private void expActionKeywords_Collapsed(object sender, RoutedEventArgs e)
{
if (!expActionKeywords.IsExpanded)
expActionKeywords.Height = Double.NaN;
}
private void expFolderLinks_Click(object sender, RoutedEventArgs e)
{
if (expFolderLinks.IsExpanded)
expFolderLinks.Height = 235;
if (!expFolderLinks.IsExpanded)
expFolderLinks.Height = Double.NaN;
expFolderLinks.Height = 215;
if (expExcludedPaths.IsExpanded)
expExcludedPaths.IsExpanded = false;
if (expActionKeywords.IsExpanded)
expActionKeywords.IsExpanded = false;
RefreshView();
}
private void expFolderLinks_Collapsed(object sender, RoutedEventArgs e)
{
if (!expFolderLinks.IsExpanded)
expFolderLinks.Height = Double.NaN;
}
private void expExcludedPaths_Click(object sender, RoutedEventArgs e)
{
if (expExcludedPaths.IsExpanded)
@ -101,6 +153,9 @@ namespace Flow.Launcher.Plugin.Explorer.Views
if (expFolderLinks.IsExpanded)
expFolderLinks.IsExpanded = false;
if (expActionKeywords.IsExpanded)
expActionKeywords.IsExpanded = false;
RefreshView();
}
@ -132,33 +187,46 @@ namespace Flow.Launcher.Plugin.Explorer.Views
private void btnEdit_Click(object sender, RoutedEventArgs e)
{
var selectedRow = lbxFolderLinks.SelectedItem as FolderLink ?? lbxExcludedPaths.SelectedItem as FolderLink;
if (selectedRow != null)
if (lbxActionKeywords.SelectedItem is ActionKeywordView)
{
var folderBrowserDialog = new FolderBrowserDialog();
folderBrowserDialog.SelectedPath = selectedRow.Path;
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
if (expFolderLinks.IsExpanded)
{
var link = viewModel.Settings.QuickFolderAccessLinks.First(x => x.Path == selectedRow.Path);
link.Path = folderBrowserDialog.SelectedPath;
}
var selectedActionKeyword = lbxActionKeywords.SelectedItem as ActionKeywordView;
if (expExcludedPaths.IsExpanded)
{
var link = viewModel.Settings.IndexSearchExcludedSubdirectoryPaths.First(x => x.Path == selectedRow.Path);
link.Path = folderBrowserDialog.SelectedPath;
}
}
var actionKeywordWindow = new ActionKeywordSetting(viewModel, actionKeywordsListView, selectedActionKeyword);
actionKeywordWindow.ShowDialog();
RefreshView();
}
else
{
string warning = viewModel.Context.API.GetTranslation("plugin_explorer_select_folder_link_warning");
MessageBox.Show(warning);
var selectedRow = lbxFolderLinks.SelectedItem as FolderLink ?? lbxExcludedPaths.SelectedItem as FolderLink;
if (selectedRow != null)
{
var folderBrowserDialog = new FolderBrowserDialog();
folderBrowserDialog.SelectedPath = selectedRow.Path;
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
if (expFolderLinks.IsExpanded)
{
var link = viewModel.Settings.QuickFolderAccessLinks.First(x => x.Path == selectedRow.Path);
link.Path = folderBrowserDialog.SelectedPath;
}
if (expExcludedPaths.IsExpanded)
{
var link = viewModel.Settings.IndexSearchExcludedSubdirectoryPaths.First(x => x.Path == selectedRow.Path);
link.Path = folderBrowserDialog.SelectedPath;
}
}
RefreshView();
}
else
{
string warning = viewModel.Context.API.GetTranslation("plugin_explorer_make_selection_warning");
MessageBox.Show(warning);
}
}
}
@ -242,4 +310,11 @@ namespace Flow.Launcher.Plugin.Explorer.Views
viewModel.OpenWindowsIndexingOptions();
}
}
public class ActionKeywordView
{
public string Description { get; set; }
public string Keyword { get; set; }
}
}

View file

@ -1,10 +1,13 @@
{
"ID": "572be03c74c642baae319fc283e561a8",
"ActionKeyword": "*",
"ActionKeywords": [
"*",
"doc:"
],
"Name": "Explorer",
"Description": "Search and manage files and folders. Explorer utilises Windows Index Search",
"Author": "Jeremy Wu",
"Version": "1.1.0",
"Version": "1.2.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll",

View file

@ -244,8 +244,6 @@ namespace Flow.Launcher.Plugin.Sys
{
Application.Current.MainWindow.Hide();
context.API.CheckForNewUpdate();
context.API.ShowMsg("Please wait...",
"Checking for new update");
return true;
}
}

View file

@ -19,8 +19,8 @@
<StackPanel VerticalAlignment="Top" Grid.Row="1" Height="106" Margin="0 20 0 0">
<Label Content="{DynamicResource flowlauncher_plugin_url_plugin_set_tip}" Height="28" Margin="0,0,155,0"
HorizontalAlignment="Left" Width="290" />
<TextBox x:Name="browserPathBox" HorizontalAlignment="Left" Height="34" TextWrapping="Wrap"
VerticalAlignment="Top" Width="311" RenderTransformOrigin="0.502,-1.668" />
<TextBox x:Name="browserPathBox" HorizontalAlignment="Left" Height="34" TextWrapping="NoWrap"
VerticalAlignment="Top" Width="311" RenderTransformOrigin="0.502,-1.668" TextChanged="OnBrowserPathTextChanged" />
<Button x:Name="viewButton" HorizontalAlignment="Left" Margin="340,-33,-1,0" Width="100"
Height="32" Click="OnChooseClick" FontSize="14"
Content="{DynamicResource flowlauncher_plugin_url_plugin_choose}" />

View file

@ -57,5 +57,10 @@ namespace Flow.Launcher.Plugin.Url
{
_settings.OpenInNewBrowserWindow = false;
}
private void OnBrowserPathTextChanged(object sender, TextChangedEventArgs e)
{
_settings.BrowserPath = browserPathBox.Text;
}
}
}

View file

@ -25,6 +25,7 @@
<system:String x:Key="flowlauncher_plugin_websearch_input_url">Please enter a URL</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_action_keyword_exist">Action keyword already exists, please enter a different one</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_succeed">Success</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_iconpath_hint">Hint: You do not need to place custom images in this directory, if Flow's version is updated they will be lost. Flow will automatically copy any images outside of this directory across to WebSearch's custom image location.</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_plugin_name">Web Searches</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_plugin_description">Allows to perform web searches</system:String>

View file

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using System.Windows.Controls;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Plugin.WebSearch
@ -21,8 +22,9 @@ namespace Flow.Launcher.Plugin.WebSearch
private CancellationTokenSource _updateSource;
private CancellationToken _updateToken;
public const string Images = "Images";
public static string ImagesDirectory;
internal const string Images = "Images";
internal static string DefaultImagesDirectory;
internal static string CustomImagesDirectory;
private readonly string SearchSourceGlobalPluginWildCardSign = "*";
@ -33,6 +35,9 @@ namespace Flow.Launcher.Plugin.WebSearch
public List<Result> Query(Query query)
{
if (FilesFolders.IsLocationPathString(query.Search))
return new List<Result>();
var searchSourceList = new List<SearchSource>();
var results = new List<Result>();
@ -169,8 +174,14 @@ namespace Flow.Launcher.Plugin.WebSearch
_context = context;
var pluginDirectory = _context.CurrentPluginMetadata.PluginDirectory;
var bundledImagesDirectory = Path.Combine(pluginDirectory, Images);
ImagesDirectory = Path.Combine(_context.CurrentPluginMetadata.PluginDirectory, Images);
Helper.ValidateDataDirectory(bundledImagesDirectory, ImagesDirectory);
// Default images directory is in the WebSearch's application folder
DefaultImagesDirectory = Path.Combine(pluginDirectory, Images);
Helper.ValidateDataDirectory(bundledImagesDirectory, DefaultImagesDirectory);
// Custom images directory is in the WebSearch's data location folder
var name = Path.GetFileNameWithoutExtension(_context.CurrentPluginMetadata.ExecuteFileName);
CustomImagesDirectory = Path.Combine(DataLocation.PluginSettingsDirectory, name, "CustomIcons");
}
#region ISettingProvider Members

View file

@ -1,29 +1,38 @@
using System.IO;
using System.IO;
using System.Windows.Media;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure;
using System.Reflection;
namespace Flow.Launcher.Plugin.WebSearch
{
public class SearchSource : BaseModel
{
public const string DefaultIcon = "web_search.png";
public string Title { get; set; }
public string ActionKeyword { get; set; }
[NotNull]
public string Icon { get; set; } = DefaultIcon;
public string Icon { get; set; } = "web_search.png";
public bool CustomIcon { get; set; } = false;
/// <summary>
/// All icon should be put under Images directory
/// Default icons are placed in Images directory in the app location.
/// Custom icons are placed in the user data directory
/// </summary>
[NotNull]
[JsonIgnore]
internal string IconPath => Path.Combine(Main.ImagesDirectory, Icon);
public string IconPath
{
get
{
if (CustomIcon)
return Path.Combine(Main.CustomImagesDirectory, Icon);
[JsonIgnore]
public ImageSource Image => ImageLoader.Load(IconPath);
return Path.Combine(Main.DefaultImagesDirectory, Icon);
}
}
public string Url { get; set; }
public bool Enabled { get; set; }
@ -36,6 +45,7 @@ namespace Flow.Launcher.Plugin.WebSearch
ActionKeyword = string.Copy(ActionKeyword),
Url = string.Copy(Url),
Icon = string.Copy(Icon),
CustomIcon = CustomIcon,
Enabled = Enabled
};
return webSearch;

View file

@ -47,7 +47,7 @@
<TextBlock Margin="10" FontSize="14" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center"
HorizontalAlignment="Right" Text="{DynamicResource flowlauncher_plugin_websearch_icon}" />
<StackPanel Orientation="Horizontal" Grid.Row="4" Grid.Column="1" Margin="10">
<Image Source="{Binding SearchSource.Image ,IsAsync=True}" Width="24" Height="24" Margin="0 0 20 0" />
<Image Name="imgPreviewIcon" Width="24" Height="24" Margin="0 0 20 0" />
<Button Click="OnSelectIconClick" Height="35"
Content="{DynamicResource flowlauncher_plugin_websearch_select_icon}" />
</StackPanel>

View file

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.IO;
using System.Windows;
using Microsoft.Win32;
using Flow.Launcher.Core.Plugin;
@ -15,6 +14,7 @@ namespace Flow.Launcher.Plugin.WebSearch
private PluginInitContext _context;
private IPublicAPI _api;
private SearchSourceViewModel _viewModel;
private string selectedNewIconImageFullPath;
public SearchSourceSettingWindow(IList<SearchSource> sources, PluginInitContext context, SearchSource old)
@ -39,6 +39,10 @@ namespace Flow.Launcher.Plugin.WebSearch
_action = action;
_context = context;
_api = _context.API;
_viewModel.SetupCustomImagesDirectory();
imgPreviewIcon.Source = _viewModel.LoadPreviewIcon(_searchSource.IconPath);
}
private void OnCancelButtonClick(object sender, RoutedEventArgs e)
@ -83,8 +87,6 @@ namespace Flow.Launcher.Plugin.WebSearch
_searchSources.Add(_searchSource);
var info = _api.GetTranslation("success");
MessageBox.Show(info);
Close();
}
else
@ -106,8 +108,6 @@ namespace Flow.Launcher.Plugin.WebSearch
var index = _searchSources.IndexOf(_oldSearchSource);
_searchSources[index] = _searchSource;
var info = _api.GetTranslation("success");
MessageBox.Show(info);
Close();
}
else
@ -115,26 +115,32 @@ namespace Flow.Launcher.Plugin.WebSearch
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
MessageBox.Show(warning);
}
if (!string.IsNullOrEmpty(selectedNewIconImageFullPath))
{
_viewModel.UpdateIconAttributes(_searchSource, selectedNewIconImageFullPath);
_viewModel.CopyNewImageToUserDataDirectoryIfRequired(
_searchSource, selectedNewIconImageFullPath, _oldSearchSource.IconPath);
}
}
private void OnSelectIconClick(object sender, RoutedEventArgs e)
{
var directory = Main.ImagesDirectory;
const string filter = "Image files (*.jpg, *.jpeg, *.gif, *.png, *.bmp) |*.jpg; *.jpeg; *.gif; *.png; *.bmp";
var dialog = new OpenFileDialog {InitialDirectory = directory, Filter = filter};
var dialog = new OpenFileDialog {InitialDirectory = Main.CustomImagesDirectory, Filter = filter};
var result = dialog.ShowDialog();
if (result == true)
{
var fullpath = dialog.FileName;
if (!string.IsNullOrEmpty(fullpath))
selectedNewIconImageFullPath = dialog.FileName;
if (!string.IsNullOrEmpty(selectedNewIconImageFullPath))
{
_searchSource.Icon = Path.GetFileName(fullpath);
if (!File.Exists(_searchSource.IconPath))
{
_searchSource.Icon = SearchSource.DefaultIcon;
MessageBox.Show($"The file should be put under {directory}");
}
if (_viewModel.ShouldProvideHint(selectedNewIconImageFullPath))
MessageBox.Show(_api.GetTranslation("flowlauncher_plugin_websearch_iconpath_hint"));
imgPreviewIcon.Source = _viewModel.LoadPreviewIcon(selectedNewIconImageFullPath);
}
}
}

View file

@ -1,7 +1,65 @@
namespace Flow.Launcher.Plugin.WebSearch
using Flow.Launcher.Infrastructure.Image;
using System;
using System.Drawing;
using System.IO;
using System.Windows;
using System.Windows.Media;
namespace Flow.Launcher.Plugin.WebSearch
{
public class SearchSourceViewModel
public class SearchSourceViewModel : BaseModel
{
public SearchSource SearchSource { get; set; }
public void UpdateIconAttributes(SearchSource selectedSearchSource, string fullpathToSelectedImage)
{
var parentDirectorySelectedImg = Directory.GetParent(fullpathToSelectedImage).ToString();
selectedSearchSource.CustomIcon = parentDirectorySelectedImg != Main.DefaultImagesDirectory;
var iconFileName = Path.GetFileName(fullpathToSelectedImage);
selectedSearchSource.Icon = iconFileName;
}
public void CopyNewImageToUserDataDirectoryIfRequired(
SearchSource selectedSearchSource, string fullpathToSelectedImage, string fullPathToOriginalImage)
{
var destinationFileNameFullPath = Path.Combine(Main.CustomImagesDirectory, Path.GetFileName(fullpathToSelectedImage));
var parentDirectorySelectedImg = Directory.GetParent(fullpathToSelectedImage).ToString();
if (parentDirectorySelectedImg != Main.CustomImagesDirectory && parentDirectorySelectedImg != Main.DefaultImagesDirectory)
{
try
{
File.Copy(fullpathToSelectedImage, destinationFileNameFullPath);
}
catch (Exception e)
{
#if DEBUG
throw e;
#else
MessageBox.Show(string.Format("Copying the selected image file to {0} has failed, changes will now be reverted", destinationFileNameFullPath));
UpdateIconAttributes(selectedSearchSource, fullPathToOriginalImage);
#endif
}
}
}
internal void SetupCustomImagesDirectory()
{
if (!Directory.Exists(Main.CustomImagesDirectory))
Directory.CreateDirectory(Main.CustomImagesDirectory);
}
internal bool ShouldProvideHint(string fullPathToSelectedImage)
{
return Directory.GetParent(fullPathToSelectedImage).ToString() == Main.DefaultImagesDirectory;
}
internal ImageSource LoadPreviewIcon(string pathToPreviewIconImage)
{
return ImageLoader.Load(pathToPreviewIconImage);
}
}
}

View file

@ -40,7 +40,7 @@
</StackPanel>
<StackPanel Grid.Row="2" HorizontalAlignment="Left" Margin="0 3 0 0">
<Label Content="Set browser from path:" Margin="0 0 350 0" HorizontalAlignment="Left" Width="140"/>
<TextBox x:Name="browserPathBox" HorizontalAlignment="Left" Margin="160,-22,0,0"
<TextBox x:Name="browserPathBox" HorizontalAlignment="Left" Margin="160,-22,0,0" TextChanged="OnBrowserPathTextChanged"
Width="214" Style="{StaticResource BrowserPathBoxStyle}"/>
<Button x:Name="viewButton" HorizontalAlignment="Left" Margin="400,-30,0,0"
Click="OnChooseClick" FontSize="13" Content="Choose" Width="80"/>

View file

@ -83,5 +83,10 @@ namespace Flow.Launcher.Plugin.WebSearch
_settings.BrowserPath = fileBrowserDialog.FileName;
}
}
private void OnBrowserPathTextChanged(object sender, TextChangedEventArgs e)
{
_settings.BrowserPath = browserPathBox.Text;
}
}
}

View file

@ -25,7 +25,7 @@
"Name": "Web Searches",
"Description": "Provide the web search ability",
"Author": "qianlifeng",
"Version": "1.0.0",
"Version": "1.0.1",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.WebSearch.dll",

View file

@ -16,6 +16,7 @@ Flow Launcher. Dedicated to make your workflow flow more seamlessly. Aimed at be
![The Flow](https://user-images.githubusercontent.com/26427004/82151677-fa9c7100-989f-11ea-9143-81de60aaf07d.gif)
- Search everything from applications, files, bookmarks, YouTube, Twitter and more. All from the comfort of your keyboard without ever touching the mouse.
- Search for file contents
- Support search using environment variable paths
- Run batch and PowerShell commands as Administrator or a different user.
- Support languages from Chinese to Italian and more.
@ -30,7 +31,6 @@ Flow Launcher. Dedicated to make your workflow flow more seamlessly. Aimed at be
Windows may complain about security due to code not being signed, this will be completed at a later stage. If you downloaded from this repo, you are good to continue the set up.
**Integrations:**
- If you want to integrate with [everything](https://www.voidtools.com/): `.exe` installer + use x64 if your windows is x64 + everything service is running. Supported version is 1.3.4.686
- If you use python plugins, install [python3](https://www.python.org/downloads/): `.exe` installer + add it to `%PATH%` or set it in flow's settings
**Usage**

Some files were not shown because too many files have changed in this diff Show more