Merge pull request #162 from Flow-Launcher/dev

Release 1.3.0 | Plugin 1.2.1
This commit is contained in:
Jeremy Wu 2020-10-14 16:04:37 +11:00 committed by GitHub
commit ebeb7167cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 540 additions and 67 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 58 KiB

BIN
Doc/app_missing_img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View file

@ -95,7 +95,7 @@ namespace Flow.Launcher.Core.Configuration
public void MoveUserDataFolder(string fromLocation, string toLocation)
{
FilesFolders.Copy(fromLocation, toLocation);
FilesFolders.CopyAll(fromLocation, toLocation);
VerifyUserDataAfterMove(fromLocation, toLocation);
}

View file

@ -91,7 +91,7 @@ namespace Flow.Launcher.Core
if (DataLocation.PortableDataLocationInUse())
{
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
FilesFolders.Copy(DataLocation.PortableDataPath, targetDestination);
FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination);
if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination))
MessageBox.Show("Flow Launcher was not able to move your user profile data to the new update version. Please manually " +
$"move your profile data folder from {DataLocation.PortableDataPath} to {targetDestination}");

View file

@ -23,8 +23,10 @@ namespace Flow.Launcher.Infrastructure
public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).ProductVersion;
public static readonly int ThumbnailSize = 64;
public static readonly string DefaultIcon = Path.Combine(ProgramDirectory, "Images", "app.png");
public static readonly string ErrorIcon = Path.Combine(ProgramDirectory, "Images", "app_error.png");
private static readonly string ImagesDirectory = Path.Combine(ProgramDirectory, "Images");
public static readonly string DefaultIcon = Path.Combine(ImagesDirectory, "app.png");
public static readonly string ErrorIcon = Path.Combine(ImagesDirectory, "app_error.png");
public static readonly string MissingImgIcon = Path.Combine(ImagesDirectory, "app_missing_img.png");
public static string PythonPath;

View file

@ -38,7 +38,7 @@ namespace Flow.Launcher.Infrastructure.Image
_imageCache.Usage = LoadStorageToConcurrentDictionary();
foreach (var icon in new[] { Constant.DefaultIcon, Constant.ErrorIcon })
foreach (var icon in new[] { Constant.DefaultIcon, Constant.MissingImgIcon })
{
ImageSource img = new BitmapImage(new Uri(icon));
img.Freeze();
@ -106,7 +106,7 @@ namespace Flow.Launcher.Infrastructure.Image
{
if (string.IsNullOrEmpty(path))
{
return new ImageResult(_imageCache[Constant.ErrorIcon], ImageType.Error);
return new ImageResult(_imageCache[Constant.MissingImgIcon], ImageType.Error);
}
if (_imageCache.ContainsKey(path))
{
@ -139,7 +139,7 @@ namespace Flow.Launcher.Infrastructure.Image
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e);
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2);
ImageSource image = _imageCache[Constant.ErrorIcon];
ImageSource image = _imageCache[Constant.MissingImgIcon];
_imageCache[path] = image;
imageResult = new ImageResult(image, ImageType.Error);
}
@ -191,8 +191,8 @@ namespace Flow.Launcher.Infrastructure.Image
}
else
{
image = _imageCache[Constant.ErrorIcon];
path = Constant.ErrorIcon;
image = _imageCache[Constant.MissingImgIcon];
path = Constant.MissingImgIcon;
}
if (type != ImageType.Error)

View file

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

View file

@ -17,7 +17,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
/// </summary>
/// <param name="sourcePath"></param>
/// <param name="targetPath"></param>
public static void Copy(this string sourcePath, string targetPath)
public static void CopyAll(this string sourcePath, string targetPath)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourcePath);
@ -50,7 +50,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(targetPath, subdir.Name);
Copy(subdir.FullName, temppath);
CopyAll(subdir.FullName, temppath);
}
}
catch (Exception e)
@ -114,7 +114,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
return Directory.Exists(path);
}
public static bool FileExits(this string filePath)
public static bool FileExists(this string filePath)
{
return File.Exists(filePath);
}
@ -124,7 +124,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
var psi = new ProcessStartInfo { FileName = FileExplorerProgramName, UseShellExecute = true, Arguments = fileOrFolderPath };
try
{
if (LocationExists(fileOrFolderPath) || FileExits(fileOrFolderPath))
if (LocationExists(fileOrFolderPath) || FileExists(fileOrFolderPath))
Process.Start(psi);
}
catch (Exception e)

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View file

@ -51,7 +51,7 @@ namespace Flow.Launcher.ViewModel
catch (Exception e)
{
Log.Exception($"|ResultViewModel.Image|IcoPath is empty and exception when calling Icon() for result <{Result.Title}> of plugin <{Result.PluginDirectory}>", e);
imagePath = Constant.ErrorIcon;
imagePath = Constant.MissingImgIcon;
}
}

View file

@ -9,6 +9,7 @@
<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>
<system:String x:Key="plugin_explorer_globalActionKeywordInvalid">Assigning the global action keyword could bring up too many results during search. Please choose a specific action keyword</system:String>
<!--Controls-->
<system:String x:Key="plugin_explorer_delete">Delete</system:String>

View file

@ -22,6 +22,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search
internal const char AllFilesFolderSearchWildcard = '>';
internal const string DefaultContentSearchActionKeyword = "doc:";
internal const char DirectorySeperator = '\\';
internal const string WindowsIndexingOptions = "srchadmin.dll";

View file

@ -6,14 +6,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search.FolderLinks
{
public class QuickFolderAccess
{
internal List<Result> FolderList(Query query, List<FolderLink> folderLinks, PluginInitContext context)
internal List<Result> FolderListMatched(Query query, List<FolderLink> folderLinks, PluginInitContext context)
{
if (string.IsNullOrEmpty(query.Search))
return folderLinks
.Select(item =>
new ResultManager(context)
.CreateFolderResult(item.Nickname, item.Path, item.Path, query))
.ToList();
return new List<Result>();
string search = query.Search.ToLower();
@ -24,5 +20,11 @@ namespace Flow.Launcher.Plugin.Explorer.Search.FolderLinks
.CreateFolderResult(item.Nickname, item.Path, item.Path, query))
.ToList();
}
internal List<Result> FolderListAll(Query query, List<FolderLink> folderLinks, PluginInitContext context)
=> folderLinks
.Select(item =>
new ResultManager(context).CreateFolderResult(item.Nickname, item.Path, item.Path, query))
.ToList();
}
}

View file

@ -34,17 +34,20 @@ namespace Flow.Launcher.Plugin.Explorer.Search
var querySearch = query.Search;
var quickFolderLinks = quickFolderAccess.FolderList(query, settings.QuickFolderAccessLinks, context);
if (quickFolderLinks.Count > 0 && query.ActionKeyword == settings.SearchActionKeyword)
return quickFolderLinks;
if (string.IsNullOrEmpty(querySearch))
return results;
if (IsFileContentSearch(query.ActionKeyword))
return WindowsIndexFileContentSearch(query, querySearch);
// This allows the user to type the assigned action keyword and only see the list of quick folder links
if (settings.QuickFolderAccessLinks.Count > 0
&& query.ActionKeyword == settings.SearchActionKeyword
&& string.IsNullOrEmpty(query.Search))
return quickFolderAccess.FolderListAll(query, settings.QuickFolderAccessLinks, context);
var quickFolderLinks = quickFolderAccess.FolderListMatched(query, settings.QuickFolderAccessLinks, context);
if (quickFolderLinks.Count > 0)
results.AddRange(quickFolderLinks);
var isEnvironmentVariable = EnvironmentVariables.IsEnvironmentVariableSearch(querySearch);
if (isEnvironmentVariable)
@ -54,7 +57,11 @@ namespace Flow.Launcher.Plugin.Explorer.Search
var isEnvironmentVariablePath = querySearch.Substring(1).Contains("%\\");
if (!FilesFolders.IsLocationPathString(querySearch) && !isEnvironmentVariablePath)
return WindowsIndexFilesAndFoldersSearch(query, querySearch);
{
results.AddRange(WindowsIndexFilesAndFoldersSearch(query, querySearch));
return results;
}
var locationPath = querySearch;
@ -137,15 +144,17 @@ namespace Flow.Launcher.Plugin.Explorer.Search
private bool UseWindowsIndexForDirectorySearch(string locationPath)
{
var pathToDirectory = FilesFolders.ReturnPreviousDirectoryIfIncompleteString(locationPath);
if (!settings.UseWindowsIndexForDirectorySearch)
return false;
if (settings.IndexSearchExcludedSubdirectoryPaths
.Any(x => FilesFolders.ReturnPreviousDirectoryIfIncompleteString(locationPath)
.Any(x => FilesFolders.ReturnPreviousDirectoryIfIncompleteString(pathToDirectory)
.StartsWith(x.Path, StringComparison.OrdinalIgnoreCase)))
return false;
return indexSearch.PathIsIndexed(locationPath);
return indexSearch.PathIsIndexed(pathToDirectory);
}
}
}

View file

@ -21,7 +21,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
private readonly ResultManager resultManager;
// Reserved keywords in oleDB
private readonly string reservedStringPattern = @"^[\/\\\$\%]+$";
private readonly string reservedStringPattern = @"^[\/\\\$\%_]+$";
internal IndexSearch(PluginInitContext context)
{
@ -51,7 +51,12 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
{
if (dataReaderResults.GetValue(0) != DBNull.Value && dataReaderResults.GetValue(1) != DBNull.Value)
{
var path = new Uri(dataReaderResults.GetString(1)).LocalPath;
// # is URI syntax for the fragment component, need to be encoded so LocalPath returns complete path
var encodedFragmentPath = dataReaderResults
.GetString(1)
.Replace("#", "%23", StringComparison.OrdinalIgnoreCase);
var path = new Uri(encodedFragmentPath).LocalPath;
if (dataReaderResults.GetString(2) == "Directory")
{

View file

@ -1,4 +1,5 @@
using Flow.Launcher.Plugin.Explorer.Search.FolderLinks;
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.FolderLinks;
using Newtonsoft.Json;
using System.Collections.Generic;
@ -22,6 +23,6 @@ namespace Flow.Launcher.Plugin.Explorer
public string SearchActionKeyword { get; set; } = Query.GlobalPluginWildcardSign;
[JsonProperty]
public string FileContentSearchActionKeyword { get; set; } = "doc:";
public string FileContentSearchActionKeyword { get; set; } = Constants.DefaultContentSearchActionKeyword;
}
}

View file

@ -54,5 +54,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
internal bool IsActionKeywordAlreadyAssigned(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
internal bool IsNewActionKeywordGlobal(string newActionKeyword) => newActionKeyword == Query.GlobalPluginWildcardSign;
}
}

View file

@ -51,8 +51,17 @@ namespace Flow.Launcher.Plugin.Explorer.Views
return;
}
if (settingsViewModel.IsNewActionKeywordGlobal(newActionKeyword)
&& currentActionKeyword.Description
== settingsViewModel.Context.API.GetTranslation("plugin_explorer_actionkeywordview_filecontentsearch"))
{
MessageBox.Show(settingsViewModel.Context.API.GetTranslation("plugin_explorer_globalActionKeywordInvalid"));
return;
}
if(!settingsViewModel.IsActionKeywordAlreadyAssigned(newActionKeyword))
if (!settingsViewModel.IsActionKeywordAlreadyAssigned(newActionKeyword))
{
settingsViewModel.UpdateActionKeyword(newActionKeyword, currentActionKeyword.Keyword);

View file

@ -7,7 +7,7 @@
"Name": "Explorer",
"Description": "Search and manage files and folders. Explorer utilises Windows Index Search",
"Author": "Jeremy Wu",
"Version": "1.2.2",
"Version": "1.2.4",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll",

View file

@ -5,7 +5,8 @@
<system:String x:Key="flowlauncher_plugin_processkiller_plugin_name">Process Killer</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_plugin_description">Kill running processes from Flow Launcher</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_kill_all">kill all "{0}" processes</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_kill_all">kill all instances of "{0}"</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_kill_all_count">kill {0} processes</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_kill_instances">kill all instances</system:String>
</ResourceDictionary>

View file

@ -52,21 +52,24 @@ namespace Flow.Launcher.Plugin.ProcessKiller
// get all non-system processes whose file path matches that of the given result (processPath)
var similarProcesses = processHelper.GetSimilarProcesses(processPath);
menuOptions.Add(new Result
if (similarProcesses.Count() > 0)
{
Title = _context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_instances"),
SubTitle = processPath,
Action = _ =>
menuOptions.Add(new Result
{
foreach (var p in similarProcesses)
Title = _context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_instances"),
SubTitle = processPath,
Action = _ =>
{
processHelper.TryKill(p);
}
foreach (var p in similarProcesses)
{
processHelper.TryKill(p);
}
return true;
},
IcoPath = processPath
});
return true;
},
IcoPath = processPath
});
}
return menuOptions;
}
@ -86,6 +89,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller
SubTitle = path,
TitleHighlightData = StringMatcher.FuzzySearch(termToSearch, p.ProcessName).MatchData,
Score = pr.Score,
ContextData = p.ProcessName,
Action = (c) =>
{
processHelper.TryKill(p);
@ -94,16 +98,18 @@ namespace Flow.Launcher.Plugin.ProcessKiller
});
}
var sortedResults = results.OrderBy(x => x.Title).ToList();
// When there are multiple results AND all of them are instances of the same executable
// add a quick option to kill them all at the top of the results.
var firstResult = results.FirstOrDefault()?.SubTitle;
if (processlist.Count > 1 && !string.IsNullOrEmpty(termToSearch) && results.All(r => r.SubTitle == firstResult))
var firstResult = sortedResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.SubTitle));
if (processlist.Count > 1 && !string.IsNullOrEmpty(termToSearch) && sortedResults.All(r => r.SubTitle == firstResult?.SubTitle))
{
results.Insert(0, new Result()
sortedResults.Insert(1, new Result()
{
IcoPath = "Images/app.png",
Title = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all"), termToSearch),
SubTitle = "",
IcoPath = firstResult?.IcoPath,
Title = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all"), firstResult?.ContextData),
SubTitle = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all_count"), processlist.Count),
Score = 200,
Action = (c) =>
{
@ -117,7 +123,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller
});
}
return results;
return sortedResults;
}
}
}

View file

@ -4,7 +4,7 @@
"Name":"Process Killer",
"Description":"kill running processes from Flow",
"Author":"Flow-Launcher",
"Version":"1.0.0",
"Version":"1.1.0",
"Language":"csharp",
"Website":"https://github.com/Flow-Launcher/Flow.Launcher.Plugin.ProcessKiller",
"IcoPath":"Images\\app.png",

View file

@ -536,7 +536,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
ProgramLogger.LogException($"|UWP|ImageFromPath|{path}" +
$"|Unable to get logo for {UserModelId} from {path} and" +
$" located in {Package.Location}", new FileNotFoundException());
return new BitmapImage(new Uri(Constant.ErrorIcon));
return new BitmapImage(new Uri(Constant.MissingImgIcon));
}
}
@ -586,7 +586,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
$"|Unable to convert background string {BackgroundColor} " +
$"to color for {Package.Location}", new InvalidOperationException());
return new BitmapImage(new Uri(Constant.ErrorIcon));
return new BitmapImage(new Uri(Constant.MissingImgIcon));
}
}
else

View file

@ -16,6 +16,6 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.2.1")]
[assembly: AssemblyFileVersion("1.2.1")]
[assembly: AssemblyInformationalVersion("1.2.1")]
[assembly: AssemblyVersion("1.3.0")]
[assembly: AssemblyFileVersion("1.3.0")]
[assembly: AssemblyInformationalVersion("1.3.0")]

View file

@ -1,4 +1,4 @@
version: '1.2.1.{build}'
version: '1.3.0.{build}'
init:
- ps: |