mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Change signature back to string to accommodate async method.
Port open Windows Context Menu feature
This commit is contained in:
parent
9d294ed71a
commit
2c3df3f4db
12 changed files with 1745 additions and 80 deletions
|
|
@ -9,6 +9,8 @@ using Flow.Launcher.Plugin.SharedCommands;
|
||||||
using Flow.Launcher.Plugin.Explorer.Search;
|
using Flow.Launcher.Plugin.Explorer.Search;
|
||||||
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
|
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
using MessageBox = System.Windows.Forms.MessageBox;
|
using MessageBox = System.Windows.Forms.MessageBox;
|
||||||
using MessageBoxIcon = System.Windows.Forms.MessageBoxIcon;
|
using MessageBoxIcon = System.Windows.Forms.MessageBoxIcon;
|
||||||
using MessageBoxButton = System.Windows.Forms.MessageBoxButtons;
|
using MessageBoxButton = System.Windows.Forms.MessageBoxButtons;
|
||||||
|
|
@ -50,14 +52,18 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
contextMenus.Add(CreateOpenWindowsIndexingOptions());
|
contextMenus.Add(CreateOpenWindowsIndexingOptions());
|
||||||
|
|
||||||
if (record.ShowIndexState)
|
if (record.ShowIndexState)
|
||||||
contextMenus.Add(new Result {Title = "From index search: " + (record.WindowsIndexed ? "Yes" : "No"),
|
contextMenus.Add(new Result
|
||||||
SubTitle = "Location: " + record.FullPath,
|
{
|
||||||
Score = 501, IcoPath = Constants.IndexImagePath});
|
Title = "From index search: " + (record.WindowsIndexed ? "Yes" : "No"),
|
||||||
|
SubTitle = "Location: " + record.FullPath,
|
||||||
|
Score = 501,
|
||||||
|
IcoPath = Constants.IndexImagePath
|
||||||
|
});
|
||||||
|
|
||||||
var icoPath = (record.Type == ResultType.File) ? Constants.FileImagePath : Constants.FolderImagePath;
|
var icoPath = (record.Type == ResultType.File) ? Constants.FileImagePath : Constants.FolderImagePath;
|
||||||
var fileOrFolder = (record.Type == ResultType.File) ? "file" : "folder";
|
var fileOrFolder = (record.Type == ResultType.File) ? "file" : "folder";
|
||||||
|
|
||||||
if (!Settings.QuickAccessLinks.Any(x => x.Path == record.FullPath))
|
if (Settings.QuickAccessLinks.All(x => x.Path != record.FullPath))
|
||||||
{
|
{
|
||||||
contextMenus.Add(new Result
|
contextMenus.Add(new Result
|
||||||
{
|
{
|
||||||
|
|
@ -65,13 +71,16 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
SubTitle = string.Format(Context.API.GetTranslation("plugin_explorer_add_to_quickaccess_subtitle"), fileOrFolder),
|
SubTitle = string.Format(Context.API.GetTranslation("plugin_explorer_add_to_quickaccess_subtitle"), fileOrFolder),
|
||||||
Action = (context) =>
|
Action = (context) =>
|
||||||
{
|
{
|
||||||
Settings.QuickAccessLinks.Add(new AccessLink { Path = record.FullPath, Type = record.Type });
|
Settings.QuickAccessLinks.Add(new AccessLink
|
||||||
|
{
|
||||||
|
Path = record.FullPath, Type = record.Type
|
||||||
|
});
|
||||||
|
|
||||||
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_addfilefoldersuccess"),
|
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_addfilefoldersuccess"),
|
||||||
string.Format(
|
string.Format(
|
||||||
Context.API.GetTranslation("plugin_explorer_addfilefoldersuccess_detail"),
|
Context.API.GetTranslation("plugin_explorer_addfilefoldersuccess_detail"),
|
||||||
fileOrFolder),
|
fileOrFolder),
|
||||||
Constants.ExplorerIconImageFullPath);
|
Constants.ExplorerIconImageFullPath);
|
||||||
|
|
||||||
ViewModel.Save();
|
ViewModel.Save();
|
||||||
|
|
||||||
|
|
@ -93,10 +102,10 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
Settings.QuickAccessLinks.Remove(Settings.QuickAccessLinks.FirstOrDefault(x => x.Path == record.FullPath));
|
Settings.QuickAccessLinks.Remove(Settings.QuickAccessLinks.FirstOrDefault(x => x.Path == record.FullPath));
|
||||||
|
|
||||||
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_removefilefoldersuccess"),
|
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_removefilefoldersuccess"),
|
||||||
string.Format(
|
string.Format(
|
||||||
Context.API.GetTranslation("plugin_explorer_removefilefoldersuccess_detail"),
|
Context.API.GetTranslation("plugin_explorer_removefilefoldersuccess_detail"),
|
||||||
fileOrFolder),
|
fileOrFolder),
|
||||||
Constants.ExplorerIconImageFullPath);
|
Constants.ExplorerIconImageFullPath);
|
||||||
|
|
||||||
ViewModel.Save();
|
ViewModel.Save();
|
||||||
|
|
||||||
|
|
@ -107,12 +116,12 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
IcoPath = Constants.RemoveQuickAccessImagePath
|
IcoPath = Constants.RemoveQuickAccessImagePath
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
contextMenus.Add(new Result
|
contextMenus.Add(new Result
|
||||||
{
|
{
|
||||||
Title = Context.API.GetTranslation("plugin_explorer_copypath"),
|
Title = Context.API.GetTranslation("plugin_explorer_copypath"),
|
||||||
SubTitle = $"Copy the current {fileOrFolder} path to clipboard",
|
SubTitle = $"Copy the current {fileOrFolder} path to clipboard",
|
||||||
Action = (context) =>
|
Action = _ =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -134,11 +143,14 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
{
|
{
|
||||||
Title = Context.API.GetTranslation("plugin_explorer_copyfilefolder") + $" {fileOrFolder}",
|
Title = Context.API.GetTranslation("plugin_explorer_copyfilefolder") + $" {fileOrFolder}",
|
||||||
SubTitle = $"Copy the {fileOrFolder} to clipboard",
|
SubTitle = $"Copy the {fileOrFolder} to clipboard",
|
||||||
Action = (context) =>
|
Action = _ =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Clipboard.SetFileDropList(new System.Collections.Specialized.StringCollection { record.FullPath });
|
Clipboard.SetFileDropList(new System.Collections.Specialized.StringCollection
|
||||||
|
{
|
||||||
|
record.FullPath
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
@ -153,7 +165,8 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
IcoPath = icoPath
|
IcoPath = icoPath
|
||||||
});
|
});
|
||||||
|
|
||||||
if (record.Type == ResultType.File || record.Type == ResultType.Folder)
|
|
||||||
|
if (record.Type is ResultType.File or ResultType.Folder)
|
||||||
contextMenus.Add(new Result
|
contextMenus.Add(new Result
|
||||||
{
|
{
|
||||||
Title = Context.API.GetTranslation("plugin_explorer_deletefilefolder") + $" {fileOrFolder}",
|
Title = Context.API.GetTranslation("plugin_explorer_deletefilefolder") + $" {fileOrFolder}",
|
||||||
|
|
@ -163,10 +176,10 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (MessageBox.Show(
|
if (MessageBox.Show(
|
||||||
string.Format(Context.API.GetTranslation("plugin_explorer_deletefilefolderconfirm"),fileOrFolder),
|
string.Format(Context.API.GetTranslation("plugin_explorer_deletefilefolderconfirm"), fileOrFolder),
|
||||||
string.Empty,
|
string.Empty,
|
||||||
MessageBoxButton.YesNo,
|
MessageBoxButton.YesNo,
|
||||||
MessageBoxIcon.Warning)
|
MessageBoxIcon.Warning)
|
||||||
== DialogResult.No)
|
== DialogResult.No)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -175,11 +188,11 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
else
|
else
|
||||||
Directory.Delete(record.FullPath, true);
|
Directory.Delete(record.FullPath, true);
|
||||||
|
|
||||||
Task.Run(() =>
|
_ = Task.Run(() =>
|
||||||
{
|
{
|
||||||
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_deletefilefoldersuccess"),
|
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_deletefilefoldersuccess"),
|
||||||
string.Format(Context.API.GetTranslation("plugin_explorer_deletefilefoldersuccess_detail"), fileOrFolder),
|
string.Format(Context.API.GetTranslation("plugin_explorer_deletefilefoldersuccess_detail"), fileOrFolder),
|
||||||
Constants.ExplorerIconImageFullPath);
|
Constants.ExplorerIconImageFullPath);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
@ -195,6 +208,52 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
IcoPath = Constants.DeleteFileFolderImagePath
|
IcoPath = Constants.DeleteFileFolderImagePath
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (record.Type is not ResultType.Volume)
|
||||||
|
{
|
||||||
|
contextMenus.Add(new Result()
|
||||||
|
{
|
||||||
|
Title = Context.API.GetTranslation("plugin_explorer_show_contextmenu_title"),
|
||||||
|
IcoPath = Constants.ShowContextMenuImagePath,
|
||||||
|
Glyph = new GlyphInfo("Segoe Fluent Icons", "\uE700"),
|
||||||
|
Action = _ =>
|
||||||
|
{
|
||||||
|
if (record.Type is ResultType.Volume)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var screenWithMouseCursor = System.Windows.Forms.Screen.FromPoint(System.Windows.Forms.Cursor.Position);
|
||||||
|
var xOfScreenCenter = screenWithMouseCursor.WorkingArea.Left + screenWithMouseCursor.WorkingArea.Width / 2;
|
||||||
|
var yOfScreenCenter = screenWithMouseCursor.WorkingArea.Top + screenWithMouseCursor.WorkingArea.Height / 2;
|
||||||
|
var showPosition = new System.Drawing.Point(xOfScreenCenter, yOfScreenCenter);
|
||||||
|
|
||||||
|
switch (record.Type)
|
||||||
|
{
|
||||||
|
case ResultType.File:
|
||||||
|
{
|
||||||
|
var fileInfos = new FileInfo[]
|
||||||
|
{
|
||||||
|
new(record.FullPath)
|
||||||
|
};
|
||||||
|
|
||||||
|
new Peter.ShellContextMenu().ShowContextMenu(fileInfos, showPosition);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ResultType.Folder:
|
||||||
|
{
|
||||||
|
var directoryInfos = new DirectoryInfo[]
|
||||||
|
{
|
||||||
|
new(record.FullPath)
|
||||||
|
};
|
||||||
|
|
||||||
|
new Peter.ShellContextMenu().ShowContextMenu(directoryInfos, showPosition);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (record.Type == ResultType.File && CanRunAsDifferentUser(record.FullPath))
|
if (record.Type == ResultType.File && CanRunAsDifferentUser(record.FullPath))
|
||||||
contextMenus.Add(new Result
|
contextMenus.Add(new Result
|
||||||
{
|
{
|
||||||
|
|
@ -248,8 +307,8 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Result CreateOpenWithEditorResult(SearchResult record)
|
private Result CreateOpenWithEditorResult(SearchResult record)
|
||||||
{
|
{
|
||||||
string editorPath = Settings.EditorPath;
|
string editorPath = Settings.EditorPath;
|
||||||
|
|
@ -277,7 +336,7 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
IcoPath = Constants.FileImagePath
|
IcoPath = Constants.FileImagePath
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result CreateOpenWithShellResult(SearchResult record)
|
private Result CreateOpenWithShellResult(SearchResult record)
|
||||||
{
|
{
|
||||||
string shellPath = Settings.ShellPath;
|
string shellPath = Settings.ShellPath;
|
||||||
|
|
@ -293,8 +352,7 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
{
|
{
|
||||||
Process.Start(new ProcessStartInfo()
|
Process.Start(new ProcessStartInfo()
|
||||||
{
|
{
|
||||||
FileName = shellPath,
|
FileName = shellPath, WorkingDirectory = record.FullPath
|
||||||
WorkingDirectory = record.FullPath
|
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -318,14 +376,17 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
SubTitle = Context.API.GetTranslation("plugin_explorer_path") + " " + record.FullPath,
|
SubTitle = Context.API.GetTranslation("plugin_explorer_path") + " " + record.FullPath,
|
||||||
Action = _ =>
|
Action = _ =>
|
||||||
{
|
{
|
||||||
if(!Settings.IndexSearchExcludedSubdirectoryPaths.Any(x => x.Path == record.FullPath))
|
if (!Settings.IndexSearchExcludedSubdirectoryPaths.Any(x => x.Path == record.FullPath))
|
||||||
Settings.IndexSearchExcludedSubdirectoryPaths.Add(new AccessLink { Path = record.FullPath });
|
Settings.IndexSearchExcludedSubdirectoryPaths.Add(new AccessLink
|
||||||
|
{
|
||||||
|
Path = record.FullPath
|
||||||
|
});
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_excludedfromindexsearch_msg"),
|
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_excludedfromindexsearch_msg"),
|
||||||
Context.API.GetTranslation("plugin_explorer_path") +
|
Context.API.GetTranslation("plugin_explorer_path") +
|
||||||
" " + record.FullPath, Constants.ExplorerIconImageFullPath);
|
" " + record.FullPath, Constants.ExplorerIconImageFullPath);
|
||||||
|
|
||||||
// so the new path can be persisted to storage and not wait till next ViewModel save.
|
// so the new path can be persisted to storage and not wait till next ViewModel save.
|
||||||
Context.API.SaveAppAllSettings();
|
Context.API.SaveAppAllSettings();
|
||||||
|
|
@ -348,11 +409,11 @@ namespace Flow.Launcher.Plugin.Explorer
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var psi = new ProcessStartInfo
|
var psi = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
FileName = "control.exe",
|
FileName = "control.exe",
|
||||||
UseShellExecute = true,
|
UseShellExecute = true,
|
||||||
Arguments = "srchadmin.dll"
|
Arguments = "srchadmin.dll"
|
||||||
};
|
};
|
||||||
|
|
||||||
Process.Start(psi);
|
Process.Start(psi);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
1615
Plugins/Flow.Launcher.Plugin.Explorer/Helper/ShellContextMenu.cs
Normal file
1615
Plugins/Flow.Launcher.Plugin.Explorer/Helper/ShellContextMenu.cs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -80,5 +80,6 @@
|
||||||
<system:String x:Key="plugin_explorer_contextmenu_remove_titletooltip">Remove from Quick Access</system:String>
|
<system:String x:Key="plugin_explorer_contextmenu_remove_titletooltip">Remove from Quick Access</system:String>
|
||||||
<system:String x:Key="plugin_explorer_remove_from_quickaccess_title">Remove from Quick Access</system:String>
|
<system:String x:Key="plugin_explorer_remove_from_quickaccess_title">Remove from Quick Access</system:String>
|
||||||
<system:String x:Key="plugin_explorer_remove_from_quickaccess_subtitle">Remove the current {0} from Quick Access</system:String>
|
<system:String x:Key="plugin_explorer_remove_from_quickaccess_subtitle">Remove the current {0} from Quick Access</system:String>
|
||||||
|
<system:String x:Key="plugin_explorer_show_contextmenu_title">Show Windows Context Menu</system:String>
|
||||||
|
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|
@ -17,6 +17,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
internal const string IndexingOptionsIconImagePath = "Images\\windowsindexingoptions.png";
|
internal const string IndexingOptionsIconImagePath = "Images\\windowsindexingoptions.png";
|
||||||
internal const string QuickAccessImagePath = "Images\\quickaccess.png";
|
internal const string QuickAccessImagePath = "Images\\quickaccess.png";
|
||||||
internal const string RemoveQuickAccessImagePath = "Images\\removequickaccess.png";
|
internal const string RemoveQuickAccessImagePath = "Images\\removequickaccess.png";
|
||||||
|
internal const string ShowContextMenuImagePath = "Images\\contextmenu.png";
|
||||||
|
|
||||||
|
|
||||||
internal const string ToolTipOpenDirectory = "Ctrl + Enter to open the directory";
|
internal const string ToolTipOpenDirectory = "Ctrl + Enter to open the directory";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
builder.Append(option.Keyword);
|
builder.Append(option.Keyword);
|
||||||
|
|
||||||
if (!option.ParentPath.IsWhiteSpace())
|
if (!string.IsNullOrWhiteSpace(option.ParentPath))
|
||||||
{
|
{
|
||||||
builder.Append($" {(option.IsRecursive ? "" : "parent:")}\"{option.ParentPath}\"");
|
builder.Append($" {(option.IsRecursive ? "" : "parent:")}\"{option.ParentPath}\"");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IAsyncEnumerable<SearchResult> SearchAsync(ReadOnlySpan<char> search, CancellationToken token)
|
public IAsyncEnumerable<SearchResult> SearchAsync(string search, CancellationToken token)
|
||||||
{
|
{
|
||||||
return EverythingApi.SearchAsync(
|
return EverythingApi.SearchAsync(
|
||||||
new EverythingSearchOption(search, Settings.SortOption),
|
new EverythingSearchOption(search, Settings.SortOption),
|
||||||
token);
|
token);
|
||||||
}
|
}
|
||||||
public IAsyncEnumerable<SearchResult> ContentSearchAsync(ReadOnlySpan<char> plainSearch,
|
public IAsyncEnumerable<SearchResult> ContentSearchAsync(string plainSearch,
|
||||||
ReadOnlySpan<char> contentSearch, CancellationToken token)
|
string contentSearch, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (!Settings.EnableEverythingContentSearch)
|
if (!Settings.EnableEverythingContentSearch)
|
||||||
{
|
{
|
||||||
|
|
@ -40,7 +40,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
|
||||||
contentSearch),
|
contentSearch),
|
||||||
token);
|
token);
|
||||||
}
|
}
|
||||||
public IAsyncEnumerable<SearchResult> EnumerateAsync(ReadOnlySpan<char> path, ReadOnlySpan<char> search, bool recursive, CancellationToken token)
|
public IAsyncEnumerable<SearchResult> EnumerateAsync(string path, string search, bool recursive, CancellationToken token)
|
||||||
{
|
{
|
||||||
return EverythingApi.SearchAsync(
|
return EverythingApi.SearchAsync(
|
||||||
new EverythingSearchOption(search,
|
new EverythingSearchOption(search,
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@ using Flow.Launcher.Plugin.Everything.Everything;
|
||||||
|
|
||||||
namespace Flow.Launcher.Plugin.Explorer.Search.Everything
|
namespace Flow.Launcher.Plugin.Explorer.Search.Everything
|
||||||
{
|
{
|
||||||
public record struct EverythingSearchOption(ReadOnlySpan<char> Keyword,
|
public record struct EverythingSearchOption(string Keyword,
|
||||||
SortOption SortOption,
|
SortOption SortOption,
|
||||||
bool IsContentSearch = false,
|
bool IsContentSearch = false,
|
||||||
ReadOnlySpan<char> ContentSearchKeyword = default,
|
string ContentSearchKeyword = default,
|
||||||
ReadOnlySpan<char> ParentPath = default,
|
string ParentPath = default,
|
||||||
bool IsRecursive = true,
|
bool IsRecursive = true,
|
||||||
int Offset = 0,
|
int Offset = 0,
|
||||||
int MaxCount = 100);
|
int MaxCount = 100);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search.IProvider
|
||||||
{
|
{
|
||||||
public interface IContentIndexProvider
|
public interface IContentIndexProvider
|
||||||
{
|
{
|
||||||
public IAsyncEnumerable<SearchResult> ContentSearchAsync(ReadOnlySpan<char> plainSearch, ReadOnlySpan<char> contentSearch, CancellationToken token = default);
|
public IAsyncEnumerable<SearchResult> ContentSearchAsync(string plainSearch, string contentSearch, CancellationToken token = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search.IProvider
|
||||||
{
|
{
|
||||||
public interface IIndexProvider
|
public interface IIndexProvider
|
||||||
{
|
{
|
||||||
public IAsyncEnumerable<SearchResult> SearchAsync(ReadOnlySpan<char> search, CancellationToken token);
|
public IAsyncEnumerable<SearchResult> SearchAsync(string search, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search.IProvider
|
||||||
{
|
{
|
||||||
public interface IPathIndexProvider
|
public interface IPathIndexProvider
|
||||||
{
|
{
|
||||||
public IAsyncEnumerable<SearchResult> EnumerateAsync(ReadOnlySpan<char> path, ReadOnlySpan<char> search, bool recursive, CancellationToken token);
|
public IAsyncEnumerable<SearchResult> EnumerateAsync(string path, string search, bool recursive, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using Flow.Launcher.Plugin.SharedCommands;
|
using Flow.Launcher.Plugin.SharedCommands;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -92,15 +93,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
internal static Result CreateDriveSpaceDisplayResult(string path, bool windowsIndexed = false)
|
internal static Result CreateDriveSpaceDisplayResult(string path, bool windowsIndexed = false)
|
||||||
{
|
{
|
||||||
var progressBarColor = "#26a0da";
|
var progressBarColor = "#26a0da";
|
||||||
int? progressValue = null;
|
|
||||||
var title = string.Empty; // hide title when use progress bar,
|
var title = string.Empty; // hide title when use progress bar,
|
||||||
var driveLetter = path.Substring(0, 1).ToUpper();
|
var driveLetter = path.Substring(0, 1).ToUpper();
|
||||||
var driveName = driveLetter + ":\\";
|
var driveName = driveLetter + ":\\";
|
||||||
DriveInfo drv = new DriveInfo(driveLetter);
|
DriveInfo drv = new DriveInfo(driveLetter);
|
||||||
var subtitle = toReadableSize(drv.AvailableFreeSpace, 2) + " free of " + toReadableSize(drv.TotalSize, 2);
|
var subtitle = toReadableSize(drv.AvailableFreeSpace, 2) + " free of " + toReadableSize(drv.TotalSize, 2);
|
||||||
double UsingSize = (Convert.ToDouble(drv.TotalSize) - Convert.ToDouble(drv.AvailableFreeSpace)) / Convert.ToDouble(drv.TotalSize) * 100;
|
double usingSize = (Convert.ToDouble(drv.TotalSize) - Convert.ToDouble(drv.AvailableFreeSpace)) / Convert.ToDouble(drv.TotalSize) * 100;
|
||||||
|
|
||||||
progressValue = Convert.ToInt32(UsingSize);
|
int? progressValue = Convert.ToInt32(usingSize);
|
||||||
|
|
||||||
if (progressValue >= 90)
|
if (progressValue >= 90)
|
||||||
progressBarColor = "#da2626";
|
progressBarColor = "#da2626";
|
||||||
|
|
@ -123,7 +123,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
SubTitleToolTip = path,
|
SubTitleToolTip = path,
|
||||||
ContextData = new SearchResult
|
ContextData = new SearchResult
|
||||||
{
|
{
|
||||||
Type = ResultType.Folder,
|
Type = ResultType.Volume,
|
||||||
FullPath = path,
|
FullPath = path,
|
||||||
ShowIndexState = true,
|
ShowIndexState = true,
|
||||||
WindowsIndexed = windowsIndexed
|
WindowsIndexed = windowsIndexed
|
||||||
|
|
@ -177,25 +177,13 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
|
|
||||||
internal static Result CreateOpenCurrentFolderResult(string path, bool windowsIndexed = false)
|
internal static Result CreateOpenCurrentFolderResult(string path, bool windowsIndexed = false)
|
||||||
{
|
{
|
||||||
var retrievedDirectoryPath = FilesFolders.ReturnPreviousDirectoryIfIncompleteString(path);
|
var folderName = path.TrimEnd(Constants.DirectorySeperator).Split(new[]
|
||||||
|
|
||||||
var folderName = retrievedDirectoryPath.TrimEnd(Constants.DirectorySeperator).Split(new[]
|
|
||||||
{
|
{
|
||||||
Path.DirectorySeparatorChar
|
Path.DirectorySeparatorChar
|
||||||
}, StringSplitOptions.None).Last();
|
}, StringSplitOptions.None).Last();
|
||||||
|
|
||||||
if (retrievedDirectoryPath.EndsWith(":\\"))
|
var title = $"Open {folderName}";
|
||||||
{
|
|
||||||
var driveLetter = path.Substring(0, 1).ToUpper();
|
|
||||||
folderName = driveLetter + " drive";
|
|
||||||
}
|
|
||||||
|
|
||||||
var title = "Open current directory";
|
|
||||||
|
|
||||||
if (retrievedDirectoryPath != path)
|
|
||||||
title = "Open " + folderName;
|
|
||||||
|
|
||||||
|
|
||||||
var subtitleFolderName = folderName;
|
var subtitleFolderName = folderName;
|
||||||
|
|
||||||
// ie. max characters can be displayed without subtitle cutting off: "Program Files (x86)"
|
// ie. max characters can be displayed without subtitle cutting off: "Program Files (x86)"
|
||||||
|
|
@ -207,20 +195,18 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
Title = title,
|
Title = title,
|
||||||
SubTitle = $"Use > to search within {subtitleFolderName}, " +
|
SubTitle = $"Use > to search within {subtitleFolderName}, " +
|
||||||
$"* to search for file extensions or >* to combine both searches.",
|
$"* to search for file extensions or >* to combine both searches.",
|
||||||
AutoCompleteText = GetPathWithActionKeyword(retrievedDirectoryPath, ResultType.Folder),
|
AutoCompleteText = GetPathWithActionKeyword(path, ResultType.Folder),
|
||||||
IcoPath = retrievedDirectoryPath,
|
IcoPath = path,
|
||||||
Score = 500,
|
Score = 500,
|
||||||
Action = c =>
|
Action = _ =>
|
||||||
{
|
{
|
||||||
Context.API.OpenDirectory(retrievedDirectoryPath);
|
Context.API.OpenDirectory(path);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
TitleToolTip = retrievedDirectoryPath,
|
|
||||||
SubTitleToolTip = retrievedDirectoryPath,
|
|
||||||
ContextData = new SearchResult
|
ContextData = new SearchResult
|
||||||
{
|
{
|
||||||
Type = ResultType.Folder,
|
Type = ResultType.Folder,
|
||||||
FullPath = retrievedDirectoryPath,
|
FullPath = path,
|
||||||
ShowIndexState = true,
|
ShowIndexState = true,
|
||||||
WindowsIndexed = windowsIndexed
|
WindowsIndexed = windowsIndexed
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,15 +54,15 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
|
||||||
queryConstructor.Directory(path, search, recursive),
|
queryConstructor.Directory(path, search, recursive),
|
||||||
token);
|
token);
|
||||||
}
|
}
|
||||||
public IAsyncEnumerable<SearchResult> SearchAsync(ReadOnlySpan<char> search, CancellationToken token)
|
public IAsyncEnumerable<SearchResult> SearchAsync(string search, CancellationToken token)
|
||||||
{
|
{
|
||||||
return WindowsIndexFilesAndFoldersSearchAsync(search, token: token);
|
return WindowsIndexFilesAndFoldersSearchAsync(search, token: token);
|
||||||
}
|
}
|
||||||
public IAsyncEnumerable<SearchResult> ContentSearchAsync(ReadOnlySpan<char> plainSearch, ReadOnlySpan<char> contentSearch, CancellationToken token)
|
public IAsyncEnumerable<SearchResult> ContentSearchAsync(string plainSearch, string contentSearch, CancellationToken token)
|
||||||
{
|
{
|
||||||
return WindowsIndexFileContentSearchAsync(contentSearch, token);
|
return WindowsIndexFileContentSearchAsync(contentSearch, token);
|
||||||
}
|
}
|
||||||
public IAsyncEnumerable<SearchResult> EnumerateAsync(ReadOnlySpan<char> path, ReadOnlySpan<char> search, bool recursive, CancellationToken token)
|
public IAsyncEnumerable<SearchResult> EnumerateAsync(string path, string search, bool recursive, CancellationToken token)
|
||||||
{
|
{
|
||||||
return WindowsIndexTopLevelFolderSearchAsync(search, path, recursive, token);
|
return WindowsIndexTopLevelFolderSearchAsync(search, path, recursive, token);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue