mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 18:57:19 +02:00
Moving Plugins from Wox.Plugin.* to Microsoft.Plugin.*. This is to rename the assemblies that get saved to the settings directory. External plugins will get saved to their on assembly folder in the future.
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using Wox.Infrastructure.Logger;
|
||||
using Wox.Infrastructure.Image;
|
||||
using Wox.Plugin.SharedCommands;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Microsoft.Plugin.Folder
|
||||
{
|
||||
internal class ContextMenuLoader : IContextMenu
|
||||
{
|
||||
private readonly PluginInitContext _context;
|
||||
|
||||
public ContextMenuLoader(PluginInitContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
|
||||
{
|
||||
var contextMenus = new List<ContextMenuResult>();
|
||||
if (selectedResult.ContextData is SearchResult record)
|
||||
{
|
||||
if (record.Type == ResultType.File)
|
||||
{
|
||||
contextMenus.Add(CreateOpenContainingFolderResult(record));
|
||||
}
|
||||
|
||||
var icoPath = (record.Type == ResultType.File) ? Main.FileImagePath : Main.FolderImagePath;
|
||||
var fileOrFolder = (record.Type == ResultType.File) ? "file" : "folder";
|
||||
contextMenus.Add(new ContextMenuResult
|
||||
{
|
||||
Title = "Copy path",
|
||||
Glyph = "\xE8C8",
|
||||
FontFamily = "Segoe MDL2 Assets",
|
||||
SubTitle = $"Copy the current {fileOrFolder} path to clipboard",
|
||||
AcceleratorKey = "C",
|
||||
AcceleratorModifiers = "Control",
|
||||
Action = (context) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(record.FullPath);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var message = "Fail to set text in clipboard";
|
||||
LogException(message, e);
|
||||
_context.API.ShowMsg(message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return contextMenus;
|
||||
}
|
||||
|
||||
private ContextMenuResult CreateOpenContainingFolderResult(SearchResult record)
|
||||
{
|
||||
return new ContextMenuResult
|
||||
{
|
||||
Title = "Open containing folder",
|
||||
Glyph = "\xE838",
|
||||
FontFamily = "Segoe MDL2 Assets",
|
||||
AcceleratorKey = "E",
|
||||
AcceleratorModifiers = "Control,Shift",
|
||||
Action = _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start("explorer.exe", $" /select,\"{record.FullPath}\"");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
var message = $"Fail to open file at {record.FullPath}";
|
||||
LogException(message, e);
|
||||
_context.API.ShowMsg(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private Result CreateOpenWithEditorResult(SearchResult record)
|
||||
{
|
||||
string editorPath = "notepad.exe"; // TODO add the ability to create a custom editor
|
||||
|
||||
var name = "Open With Editor: " + Path.GetFileNameWithoutExtension(editorPath);
|
||||
return new Result
|
||||
{
|
||||
Title = name,
|
||||
Action = _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(editorPath, record.FullPath);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var message = $"Fail to editor for file at {record.FullPath}";
|
||||
LogException(message, e);
|
||||
_context.API.ShowMsg(message);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
IcoPath = editorPath
|
||||
};
|
||||
}
|
||||
|
||||
public void LogException(string message, Exception e)
|
||||
{
|
||||
Log.Exception($"|Microsoft.Plugin.Folder.ContextMenu|{message}", e);
|
||||
}
|
||||
|
||||
private bool CanRunAsDifferentUser(string path)
|
||||
{
|
||||
switch(Path.GetExtension(path))
|
||||
{
|
||||
case ".exe":
|
||||
case ".bat":
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SearchResult
|
||||
{
|
||||
public string FullPath { get; set; }
|
||||
public ResultType Type { get; set; }
|
||||
}
|
||||
|
||||
public enum ResultType
|
||||
{
|
||||
Volume,
|
||||
Folder,
|
||||
File
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.Plugin.Folder
|
||||
{
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
public class FolderLink
|
||||
{
|
||||
[JsonProperty]
|
||||
public string Path { get; set; }
|
||||
|
||||
public string Nickname =>
|
||||
Path.Split(new[] { System.IO.Path.DirectorySeparatorChar }, StringSplitOptions.None)
|
||||
.Last()
|
||||
+ " (" + System.IO.Path.GetDirectoryName(Path) + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<UserControl x:Class="Microsoft.Plugin.Folder.FileSystemSettings"
|
||||
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"
|
||||
d:DesignHeight="300" d:DesignWidth="500">
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="50"/>
|
||||
</Grid.RowDefinitions>
|
||||
<ListView x:Name="lbxFolders" Grid.Row="0" AllowDrop="True"
|
||||
Drop="lbxFolders_Drop"
|
||||
DragEnter="lbxFolders_DragEnter">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="{DynamicResource wox_plugin_folder_folder_path}" Width="180">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path}"/>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
<StackPanel Grid.Row="1" HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Button x:Name="btnDelete" Click="btnDelete_Click" Width="100" Margin="10" Content="{DynamicResource wox_plugin_folder_delete}"/>
|
||||
<Button x:Name="btnEdit" Click="btnEdit_Click" Width="100" Margin="10" Content="{DynamicResource wox_plugin_folder_edit}"/>
|
||||
<Button x:Name="btnAdd" Click="btnAdd_Click" Width="100" Margin="10" Content="{DynamicResource wox_plugin_folder_add}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,131 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using Wox.Plugin;
|
||||
using DataFormats = System.Windows.DataFormats;
|
||||
using DragDropEffects = System.Windows.DragDropEffects;
|
||||
using DragEventArgs = System.Windows.DragEventArgs;
|
||||
using MessageBox = System.Windows.MessageBox;
|
||||
|
||||
namespace Microsoft.Plugin.Folder
|
||||
{
|
||||
|
||||
public partial class FileSystemSettings
|
||||
{
|
||||
private IPublicAPI woxAPI;
|
||||
private Settings _settings;
|
||||
|
||||
public FileSystemSettings(IPublicAPI woxAPI, Settings settings)
|
||||
{
|
||||
this.woxAPI = woxAPI;
|
||||
InitializeComponent();
|
||||
_settings = settings;
|
||||
lbxFolders.ItemsSource = _settings.FolderLinks;
|
||||
}
|
||||
|
||||
private void btnDelete_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectedFolder = lbxFolders.SelectedItem as FolderLink;
|
||||
if (selectedFolder != null)
|
||||
{
|
||||
string msg = string.Format(woxAPI.GetTranslation("wox_plugin_folder_delete_folder_link"), selectedFolder.Path);
|
||||
|
||||
if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
|
||||
{
|
||||
_settings.FolderLinks.Remove(selectedFolder);
|
||||
lbxFolders.Items.Refresh();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string warning = woxAPI.GetTranslation("wox_plugin_folder_select_folder_link_warning");
|
||||
MessageBox.Show(warning);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnEdit_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectedFolder = lbxFolders.SelectedItem as FolderLink;
|
||||
if (selectedFolder != null)
|
||||
{
|
||||
var folderBrowserDialog = new FolderBrowserDialog();
|
||||
folderBrowserDialog.SelectedPath = selectedFolder.Path;
|
||||
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
var link = _settings.FolderLinks.First(x => x.Path == selectedFolder.Path);
|
||||
link.Path = folderBrowserDialog.SelectedPath;
|
||||
}
|
||||
|
||||
lbxFolders.Items.Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
string warning = woxAPI.GetTranslation("wox_plugin_folder_select_folder_link_warning");
|
||||
MessageBox.Show(warning);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnAdd_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var folderBrowserDialog = new FolderBrowserDialog();
|
||||
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
var newFolder = new FolderLink
|
||||
{
|
||||
Path = folderBrowserDialog.SelectedPath
|
||||
};
|
||||
|
||||
if (_settings.FolderLinks == null)
|
||||
{
|
||||
_settings.FolderLinks = new List<FolderLink>();
|
||||
}
|
||||
|
||||
_settings.FolderLinks.Add(newFolder);
|
||||
}
|
||||
|
||||
lbxFolders.Items.Refresh();
|
||||
}
|
||||
|
||||
private void lbxFolders_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
|
||||
|
||||
if (files != null && files.Count() > 0)
|
||||
{
|
||||
if (_settings.FolderLinks == null)
|
||||
{
|
||||
_settings.FolderLinks = new List<FolderLink>();
|
||||
}
|
||||
|
||||
foreach (string s in files)
|
||||
{
|
||||
if (Directory.Exists(s))
|
||||
{
|
||||
var newFolder = new FolderLink
|
||||
{
|
||||
Path = s
|
||||
};
|
||||
|
||||
_settings.FolderLinks.Add(newFolder);
|
||||
}
|
||||
|
||||
lbxFolders.Items.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void lbxFolders_DragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
{
|
||||
e.Effects = DragDropEffects.Link;
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Effects = DragDropEffects.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 501 B |
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 290 B |
Binary file not shown.
|
After Width: | Height: | Size: 468 B |
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
@@ -0,0 +1,15 @@
|
||||
<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="wox_plugin_folder_delete">Löschen</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_edit">Bearbeiten</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_add">Hinzufügen</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_folder_path">Ordnerpfad</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">Bitte wähle eine Ordnerverknüpfung</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_delete_folder_link">Bist du sicher {0} zu löschen?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_folder_plugin_name">Ordner</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_plugin_description">Öffne deine Lieblingsordner direkt von Wox aus</system:String>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,15 @@
|
||||
<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="wox_plugin_folder_delete">Delete</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_edit">Edit</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_add">Add</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_folder_path">Folder Path</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">Please select a folder link</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_delete_folder_link">Are you sure you want to delete {0}?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_folder_plugin_name">Folder</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_plugin_description">Open favorite folder from Wox directly</system:String>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,15 @@
|
||||
<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="wox_plugin_folder_delete">Usuń</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_edit">Edytuj</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_add">Dodaj</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_folder_path">Ścieżka folderu</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">Musisz wybrać któryś folder z listy</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_delete_folder_link">Czy jesteś pewien że chcesz usunąć {0}?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_folder_plugin_name">Foldery</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_plugin_description">Otwórz ulubione foldery bezpośrednio z poziomu Woxa</system:String>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,15 @@
|
||||
<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="wox_plugin_folder_delete">Sil</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_edit">Düzenle</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_add">Ekle</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_folder_path">Klasör Konumu</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">Lütfen bir klasör bağlantısı seçin</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_delete_folder_link">{0} bağlantısını silmek istediğinize emin misiniz?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_folder_plugin_name">Klasör</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_plugin_description">Favori klasörünüzü doğrudan Wox'tan açın</system:String>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,15 @@
|
||||
<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="wox_plugin_folder_delete">删除</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_edit">编辑</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_add">添加</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_folder_path">文件夹路径</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">请选择一个文件夹</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_delete_folder_link">你确定要删除{0}吗?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_folder_plugin_name">文件夹</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_plugin_description">在Wox中直接打开收藏的文件夹</system:String>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,15 @@
|
||||
<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="wox_plugin_folder_delete">刪除</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_edit">編輯</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_add">新增</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_folder_path">資料夾路徑</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">請選擇一個資料夾</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_delete_folder_link">你確認要刪除{0}嗎?</system:String>
|
||||
|
||||
<system:String x:Key="wox_plugin_folder_plugin_name">資料夾</system:String>
|
||||
<system:String x:Key="wox_plugin_folder_plugin_description">在 Wox 中直接開啟收藏的資料夾</system:String>
|
||||
|
||||
</ResourceDictionary>
|
||||
294
src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Main.cs
Normal file
294
src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Main.cs
Normal file
@@ -0,0 +1,294 @@
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Infrastructure.Storage;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Microsoft.Plugin.Folder
|
||||
{
|
||||
public class Main : IPlugin, ISettingProvider, IPluginI18n, ISavable, IContextMenu
|
||||
{
|
||||
public const string FolderImagePath = "Images\\folder.png";
|
||||
public const string FileImagePath = "Images\\file.png";
|
||||
public const string DeleteFileFolderImagePath = "Images\\deletefilefolder.png";
|
||||
public const string CopyImagePath = "Images\\copy.png";
|
||||
|
||||
private const string _fileExplorerProgramName = "explorer";
|
||||
private static List<string> _driverNames;
|
||||
private PluginInitContext _context;
|
||||
|
||||
private readonly Settings _settings;
|
||||
private readonly PluginJsonStorage<Settings> _storage;
|
||||
private IContextMenu _contextMenuLoader;
|
||||
|
||||
public Main()
|
||||
{
|
||||
_storage = new PluginJsonStorage<Settings>();
|
||||
_settings = _storage.Load();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
_storage.Save();
|
||||
}
|
||||
|
||||
public Control CreateSettingPanel()
|
||||
{
|
||||
return new FileSystemSettings(_context.API, _settings);
|
||||
}
|
||||
|
||||
public void Init(PluginInitContext context)
|
||||
{
|
||||
_context = context;
|
||||
_contextMenuLoader = new ContextMenuLoader(context);
|
||||
InitialDriverList();
|
||||
}
|
||||
|
||||
public List<Result> Query(Query query)
|
||||
{
|
||||
var results = GetUserFolderResults(query);
|
||||
|
||||
string search = query.Search.ToLower();
|
||||
if (!IsDriveOrSharedFolder(search))
|
||||
return results;
|
||||
|
||||
results.AddRange(QueryInternal_Directory_Exists(query));
|
||||
|
||||
// todo why was this hack here?
|
||||
foreach (var result in results)
|
||||
{
|
||||
result.Score += 10;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private static bool IsDriveOrSharedFolder(string search)
|
||||
{
|
||||
if (search.StartsWith(@"\\"))
|
||||
{ // share folder
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_driverNames != null && _driverNames.Any(search.StartsWith))
|
||||
{ // normal drive letter
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_driverNames == null && search.Length > 2 && char.IsLetter(search[0]) && search[1] == ':')
|
||||
{ // when we don't have the drive letters we can try...
|
||||
return true; // we don't know so let's give it the possibility
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Result CreateFolderResult(string title, string subtitle, string path, Query query)
|
||||
{
|
||||
return new Result
|
||||
{
|
||||
Title = title,
|
||||
IcoPath = path,
|
||||
SubTitle = "Folder: " + subtitle,
|
||||
QueryTextDisplay = path,
|
||||
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
|
||||
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path },
|
||||
Action = c =>
|
||||
{
|
||||
Process.Start(_fileExplorerProgramName, path);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private List<Result> GetUserFolderResults(Query query)
|
||||
{
|
||||
string search = query.Search.ToLower();
|
||||
var userFolderLinks = _settings.FolderLinks.Where(
|
||||
x => x.Nickname.StartsWith(search, StringComparison.OrdinalIgnoreCase));
|
||||
var results = userFolderLinks.Select(item =>
|
||||
CreateFolderResult(item.Nickname, item.Path, item.Path, query)).ToList();
|
||||
return results;
|
||||
}
|
||||
|
||||
private void InitialDriverList()
|
||||
{
|
||||
if (_driverNames == null)
|
||||
{
|
||||
_driverNames = new List<string>();
|
||||
var allDrives = DriveInfo.GetDrives();
|
||||
foreach (DriveInfo driver in allDrives)
|
||||
{
|
||||
_driverNames.Add(driver.Name.ToLower().TrimEnd('\\'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly char[] _specialSearchChars = new char[]
|
||||
{
|
||||
'?', '*', '>'
|
||||
};
|
||||
|
||||
private List<Result> QueryInternal_Directory_Exists(Query query)
|
||||
{
|
||||
var search = query.Search;
|
||||
var results = new List<Result>();
|
||||
var hasSpecial = search.IndexOfAny(_specialSearchChars) >= 0;
|
||||
string incompleteName = "";
|
||||
if (hasSpecial || !Directory.Exists(search + "\\"))
|
||||
{
|
||||
// if folder doesn't exist, we want to take the last part and use it afterwards to help the user
|
||||
// find the right folder.
|
||||
int index = search.LastIndexOf('\\');
|
||||
if (index > 0 && index < (search.Length - 1))
|
||||
{
|
||||
incompleteName = search.Substring(index + 1).ToLower();
|
||||
search = search.Substring(0, index + 1);
|
||||
if (!Directory.Exists(search))
|
||||
{
|
||||
return results;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return results;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// folder exist, add \ at the end of doesn't exist
|
||||
if (!search.EndsWith("\\"))
|
||||
{
|
||||
search += "\\";
|
||||
}
|
||||
}
|
||||
|
||||
results.Add(CreateOpenCurrentFolderResult(incompleteName, search));
|
||||
|
||||
var searchOption = SearchOption.TopDirectoryOnly;
|
||||
incompleteName += "*";
|
||||
|
||||
// give the ability to search all folder when starting with >
|
||||
if (incompleteName.StartsWith(">"))
|
||||
{
|
||||
searchOption = SearchOption.AllDirectories;
|
||||
|
||||
// match everything before and after search term using supported wildcard '*', ie. *searchterm*
|
||||
incompleteName = "*" + incompleteName.Substring(1);
|
||||
}
|
||||
|
||||
var folderList = new List<Result>();
|
||||
var fileList = new List<Result>();
|
||||
|
||||
try
|
||||
{
|
||||
// search folder and add results
|
||||
var directoryInfo = new DirectoryInfo(search);
|
||||
var fileSystemInfos = directoryInfo.GetFileSystemInfos(incompleteName, searchOption);
|
||||
|
||||
foreach (var fileSystemInfo in fileSystemInfos)
|
||||
{
|
||||
if ((fileSystemInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue;
|
||||
|
||||
if(fileSystemInfo is DirectoryInfo)
|
||||
{
|
||||
var folderSubtitleString = fileSystemInfo.FullName;
|
||||
|
||||
folderList.Add(CreateFolderResult(fileSystemInfo.Name, folderSubtitleString, fileSystemInfo.FullName, query));
|
||||
}
|
||||
else
|
||||
{
|
||||
fileList.Add(CreateFileResult(fileSystemInfo.FullName, query));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is UnauthorizedAccessException || e is ArgumentException)
|
||||
{
|
||||
results.Add(new Result { Title = e.Message, Score = 501 });
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
// Intial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection.
|
||||
return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList();
|
||||
}
|
||||
|
||||
private static Result CreateFileResult(string filePath, Query query)
|
||||
{
|
||||
var result = new Result
|
||||
{
|
||||
Title = Path.GetFileName(filePath),
|
||||
SubTitle = "Folder: " + filePath,
|
||||
IcoPath = filePath,
|
||||
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, Path.GetFileName(filePath)).MatchData,
|
||||
Action = c =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(_fileExplorerProgramName, filePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message, "Could not start " + filePath);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Result CreateOpenCurrentFolderResult(string incompleteName, string search)
|
||||
{
|
||||
var firstResult = "Open " + search;
|
||||
|
||||
var folderName = search.TrimEnd('\\').Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None).Last();
|
||||
|
||||
return new Result
|
||||
{
|
||||
Title = firstResult,
|
||||
QueryTextDisplay = search,
|
||||
SubTitle = $"Folder: Use > to search within the directory. Use * to search for file extensions. Or use both >*.",
|
||||
IcoPath = search,
|
||||
Score = 500,
|
||||
Action = c =>
|
||||
{
|
||||
Process.Start(_fileExplorerProgramName, search);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public string GetTranslatedPluginTitle()
|
||||
{
|
||||
return _context.API.GetTranslation("wox_plugin_folder_plugin_name");
|
||||
}
|
||||
|
||||
public string GetTranslatedPluginDescription()
|
||||
{
|
||||
return _context.API.GetTranslation("wox_plugin_folder_plugin_description");
|
||||
}
|
||||
|
||||
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
|
||||
{
|
||||
return _contextMenuLoader.LoadContextMenus(selectedResult);
|
||||
}
|
||||
|
||||
public void UpdateSettings(PowerLauncherSettings settings)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<ProjectGuid>{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}</ProjectGuid>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.Plugin.Folder</RootNamespace>
|
||||
<AssemblyName>Microsoft.Plugin.Folder</AssemblyName>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Microsoft.Plugin.Folder\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutputPath>..\..\..\..\..\x64\Release\modules\launcher\Plugins\Microsoft.Plugin.Folder\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="plugin.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Include="FolderPluginSettings.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<None Include="Images\copy.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Images\deletefilefolder.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Include="Images\file.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="Images\user.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Include="Languages\en.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\zh-cn.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\zh-tw.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\de.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\pl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\tr.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\core\Microsoft.PowerToys.Settings.UI.Lib\Microsoft.PowerToys.Settings.UI.Lib.csproj" />
|
||||
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Images\folder.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="System.Runtime" Version="4.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Wox.Infrastructure.Storage;
|
||||
|
||||
namespace Microsoft.Plugin.Folder
|
||||
{
|
||||
public class Settings
|
||||
{
|
||||
[JsonProperty]
|
||||
public List<FolderLink> FolderLinks { get; set; } = new List<FolderLink>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"ID":"B4D3B69656E14D44865C8D818EAE47C4",
|
||||
"ActionKeyword":"*",
|
||||
"Name":"Folder",
|
||||
"Description":"Open favorite folder from wox directorily",
|
||||
"Author":"qianlifeng",
|
||||
"Version":"1.0.0",
|
||||
"Language":"csharp",
|
||||
"Website":"http://www.wox.one/plugin",
|
||||
"ExecuteFileName":"Microsoft.Plugin.Folder.dll",
|
||||
"IcoPath":"Images\\folder.png"
|
||||
}
|
||||
Reference in New Issue
Block a user