Merge branch 'dev' into explorer_prompt_deletion
BIN
Doc/Logo/app_error.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
Doc/Logo/logo.ico
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
Doc/Logo/logo.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
1
Doc/Logo/logo.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 382.6 382.5"><defs><linearGradient id="a" x2="249.9" y1="191.3" y2="191.3" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#1b9de2"/><stop offset=".2" stop-color="#1595df"/><stop offset=".7" stop-color="#0680d7"/><stop offset="1" stop-color="#0078d4"/></linearGradient><linearGradient id="b" x1="697.3" x2="809.9" y1="499.2" y2="499.2" gradientTransform="rotate(49.2 809.6 -269.1)" xlink:href="#a"/><linearGradient id="c" x1="143.6" x2="393.5" y1="249.8" y2="249.8" gradientTransform="rotate(180 263.1 220.5)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0c59a4"/><stop offset="1" stop-color="#114a8b"/></linearGradient></defs><path fill="url(#a)" d="M117 382.5H0v-189C0 90.7 84 0 186.9 0h63v120.4h-54.6c-46.8 0-78 31.2-78 78l-.1 184.1z"/><path fill="url(#b)" d="M249.9 182.6l.2-46.8h-54.7c-39 0-62.4 23.4-62.4 62.4l-.2 47 54.6-.1c39 0 62.5-23.4 62.5-62.5z"/><path fill="url(#c)" d="M265.5 0h117v189c0 102.8-84 193.5-186.8 193.5h-63V262.1h54.6c46.9 0 78.1-31.2 78.1-78L265.5 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Doc/Logo/logo128.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Doc/Logo/logo16.png
Normal file
|
After Width: | Height: | Size: 409 B |
BIN
Doc/Logo/logo256.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
Doc/Logo/logo32.png
Normal file
|
After Width: | Height: | Size: 663 B |
BIN
Doc/Logo/logo48.png
Normal file
|
After Width: | Height: | Size: 1,019 B |
BIN
Doc/Logo/logo512.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Doc/Logo/logo64.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Doc/Logo/resources/flow-header-landscape-transparent.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
Doc/Logo/resources/flow-header-landscape.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
Doc/Logo/resources/flow-header-square-transparent.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
Doc/Logo/resources/flow-header-square.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
2249
Doc/Logo/resources/flow-logo.ai
Normal file
2436
Doc/Logo/resources/preview.pdf
Normal file
BIN
Doc/app.ico
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 114 KiB |
BIN
Doc/app.png
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB |
|
|
@ -32,10 +32,9 @@ namespace Flow.Launcher.Core.Configuration
|
|||
try
|
||||
{
|
||||
MoveUserDataFolder(DataLocation.PortableDataPath, DataLocation.RoamingDataPath);
|
||||
#if DEBUG
|
||||
#if !DEBUG
|
||||
// Create shortcuts and uninstaller are not required in debug mode,
|
||||
// otherwise will repoint the path of the actual installed production version to the debug version
|
||||
#else
|
||||
CreateShortcuts();
|
||||
CreateUninstallerEntry();
|
||||
#endif
|
||||
|
|
@ -48,10 +47,7 @@ namespace Flow.Launcher.Core.Configuration
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
#if !DEBUG
|
||||
Log.Exception("Portable", "Error occured while disabling portable mode", e);
|
||||
#endif
|
||||
throw;
|
||||
Log.Exception("|Portable.DisablePortableMode|Error occured while disabling portable mode", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,10 +56,9 @@ namespace Flow.Launcher.Core.Configuration
|
|||
try
|
||||
{
|
||||
MoveUserDataFolder(DataLocation.RoamingDataPath, DataLocation.PortableDataPath);
|
||||
#if DEBUG
|
||||
#if !DEBUG
|
||||
// Remove shortcuts and uninstaller are not required in debug mode,
|
||||
// otherwise will delete the actual installed production version
|
||||
#else
|
||||
RemoveShortcuts();
|
||||
RemoveUninstallerEntry();
|
||||
#endif
|
||||
|
|
@ -76,10 +71,7 @@ namespace Flow.Launcher.Core.Configuration
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
#if !DEBUG
|
||||
Log.Exception("Portable", "Error occured while enabling portable mode", e);
|
||||
#endif
|
||||
throw;
|
||||
Log.Exception("|Portable.EnablePortableMode|Error occured while enabling portable mode", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,14 +117,13 @@ namespace Flow.Launcher.Core.Configuration
|
|||
public void CreateUninstallerEntry()
|
||||
{
|
||||
var uninstallRegSubKey = @"Software\Microsoft\Windows\CurrentVersion\Uninstall";
|
||||
// NB: Sometimes the Uninstall key doesn't exist
|
||||
using (var parentKey =
|
||||
RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default)
|
||||
.CreateSubKey("Uninstall", RegistryKeyPermissionCheck.ReadWriteSubTree)) {; }
|
||||
|
||||
var key = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default)
|
||||
.CreateSubKey(uninstallRegSubKey + "\\" + Constant.FlowLauncher, RegistryKeyPermissionCheck.ReadWriteSubTree);
|
||||
key.SetValue("DisplayIcon", Constant.ApplicationDirectory + "\\app.ico", RegistryValueKind.String);
|
||||
using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default))
|
||||
using (var subKey1 = baseKey.CreateSubKey(uninstallRegSubKey, RegistryKeyPermissionCheck.ReadWriteSubTree))
|
||||
using (var subKey2 = subKey1.CreateSubKey(Constant.FlowLauncher, RegistryKeyPermissionCheck.ReadWriteSubTree))
|
||||
{
|
||||
subKey2.SetValue("DisplayIcon", Path.Combine(Constant.ApplicationDirectory, "app.ico"), RegistryValueKind.String);
|
||||
}
|
||||
|
||||
using (var portabilityUpdater = NewUpdateManager())
|
||||
{
|
||||
|
|
@ -142,7 +133,10 @@ namespace Flow.Launcher.Core.Configuration
|
|||
|
||||
internal void IndicateDeletion(string filePathTodelete)
|
||||
{
|
||||
using (StreamWriter sw = File.CreateText(filePathTodelete + "\\" + DataLocation.DeletionIndicatorFile)){}
|
||||
var deleteFilePath = Path.Combine(filePathTodelete, DataLocation.DeletionIndicatorFile);
|
||||
using (var _ = File.CreateText(deleteFilePath))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
|
|
@ -152,21 +146,18 @@ namespace Flow.Launcher.Core.Configuration
|
|||
public void PreStartCleanUpAfterPortabilityUpdate()
|
||||
{
|
||||
// Specify here so this method does not rely on other environment variables to initialise
|
||||
var portableDataPath = Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location.NonNull()).ToString(), "UserData");
|
||||
var roamingDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher");
|
||||
var portableDataDir = Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location.NonNull()).ToString(), "UserData");
|
||||
var roamingDataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher");
|
||||
|
||||
bool DataLocationPortableDeleteRequired = false;
|
||||
bool DataLocationRoamingDeleteRequired = false;
|
||||
// Get full path to the .dead files for each case
|
||||
var portableDataDeleteFilePath = Path.Combine(portableDataDir, DataLocation.DeletionIndicatorFile);
|
||||
var roamingDataDeleteFilePath = Path.Combine(roamingDataDir, DataLocation.DeletionIndicatorFile);
|
||||
|
||||
if ((roamingDataPath + "\\" + DataLocation.DeletionIndicatorFile).FileExits())
|
||||
DataLocationRoamingDeleteRequired = true;
|
||||
|
||||
if ((portableDataPath + "\\" + DataLocation.DeletionIndicatorFile).FileExits())
|
||||
DataLocationPortableDeleteRequired = true;
|
||||
|
||||
if (DataLocationRoamingDeleteRequired)
|
||||
// If the data folder in %appdata% is marked for deletion,
|
||||
// delete it and prompt the user to pick the portable data location
|
||||
if (File.Exists(roamingDataDeleteFilePath))
|
||||
{
|
||||
FilesFolders.RemoveFolderIfExists(roamingDataPath);
|
||||
FilesFolders.RemoveFolderIfExists(roamingDataDir);
|
||||
|
||||
if (MessageBox.Show("Flow Launcher has detected you enabled portable mode, " +
|
||||
"would you like to move it to a different location?", string.Empty,
|
||||
|
|
@ -176,18 +167,15 @@ namespace Flow.Launcher.Core.Configuration
|
|||
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(DataLocationPortableDeleteRequired)
|
||||
// Otherwise, if the portable data folder is marked for deletion,
|
||||
// delete it and notify the user about it.
|
||||
else if (File.Exists(portableDataDeleteFilePath))
|
||||
{
|
||||
FilesFolders.RemoveFolderIfExists(portableDataPath);
|
||||
FilesFolders.RemoveFolderIfExists(portableDataDir);
|
||||
|
||||
MessageBox.Show("Flow Launcher has detected you disabled portable mode, " +
|
||||
"the relevant shortcuts and uninstaller entry have been created");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +184,7 @@ namespace Flow.Launcher.Core.Configuration
|
|||
var roamingLocationExists = DataLocation.RoamingDataPath.LocationExists();
|
||||
var portableLocationExists = DataLocation.PortableDataPath.LocationExists();
|
||||
|
||||
if(roamingLocationExists && portableLocationExists)
|
||||
if (roamingLocationExists && portableLocationExists)
|
||||
{
|
||||
MessageBox.Show(string.Format("Flow Launcher detected your user data exists both in {0} and " +
|
||||
"{1}. {2}{2}Please delete {1} in order to proceed. No changes have occured.",
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Flow.Launcher.Infrastructure.Exception;
|
||||
using Flow.Launcher.Infrastructure;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
using Flow.Launcher.Plugin;
|
||||
|
||||
|
|
@ -13,24 +12,16 @@ namespace Flow.Launcher.Core.Plugin
|
|||
|
||||
internal abstract class PluginConfig
|
||||
{
|
||||
private const string PluginConfigName = "plugin.json";
|
||||
private static readonly List<PluginMetadata> PluginMetadatas = new List<PluginMetadata>();
|
||||
|
||||
/// <summary>
|
||||
/// Parse plugin metadata in giving directories
|
||||
/// Parse plugin metadata in the given directories
|
||||
/// </summary>
|
||||
/// <param name="pluginDirectories"></param>
|
||||
/// <returns></returns>
|
||||
public static List<PluginMetadata> Parse(string[] pluginDirectories)
|
||||
{
|
||||
PluginMetadatas.Clear();
|
||||
var allPluginMetadata = new List<PluginMetadata>();
|
||||
var directories = pluginDirectories.SelectMany(Directory.GetDirectories);
|
||||
ParsePluginConfigs(directories);
|
||||
return PluginMetadatas;
|
||||
}
|
||||
|
||||
private static void ParsePluginConfigs(IEnumerable<string> directories)
|
||||
{
|
||||
// todo use linq when diable plugin is implmented since parallel.foreach + list is not thread saft
|
||||
foreach (var directory in directories)
|
||||
{
|
||||
|
|
@ -50,15 +41,17 @@ namespace Flow.Launcher.Core.Plugin
|
|||
PluginMetadata metadata = GetPluginMetadata(directory);
|
||||
if (metadata != null)
|
||||
{
|
||||
PluginMetadatas.Add(metadata);
|
||||
allPluginMetadata.Add(metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allPluginMetadata;
|
||||
}
|
||||
|
||||
private static PluginMetadata GetPluginMetadata(string pluginDirectory)
|
||||
{
|
||||
string configPath = Path.Combine(pluginDirectory, PluginConfigName);
|
||||
string configPath = Path.Combine(pluginDirectory, Constant.PluginMetadataFileName);
|
||||
if (!File.Exists(configPath))
|
||||
{
|
||||
Log.Error($"|PluginConfig.GetPluginMetadata|Didn't find config file <{configPath}>");
|
||||
|
|
@ -81,7 +74,6 @@ namespace Flow.Launcher.Core.Plugin
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (!AllowedLanguage.IsAllowed(metadata.Language))
|
||||
{
|
||||
Log.Error($"|PluginConfig.GetPluginMetadata|Invalid language <{metadata.Language}> for config <{configPath}>");
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using Newtonsoft.Json;
|
||||
using Flow.Launcher.Plugin;
|
||||
using Flow.Launcher.Infrastructure;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
|
||||
namespace Flow.Launcher.Core.Plugin
|
||||
{
|
||||
|
|
@ -13,28 +15,28 @@ namespace Flow.Launcher.Core.Plugin
|
|||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
string tempFoler = Path.Combine(Path.GetTempPath(), "flowlauncher\\plugins");
|
||||
if (Directory.Exists(tempFoler))
|
||||
string tempFolder = Path.Combine(Path.GetTempPath(), "flowlauncher", "plugins");
|
||||
if (Directory.Exists(tempFolder))
|
||||
{
|
||||
Directory.Delete(tempFoler, true);
|
||||
Directory.Delete(tempFolder, true);
|
||||
}
|
||||
UnZip(path, tempFoler, true);
|
||||
UnZip(path, tempFolder, true);
|
||||
|
||||
string iniPath = Path.Combine(tempFoler, "plugin.json");
|
||||
if (!File.Exists(iniPath))
|
||||
string jsonPath = Path.Combine(tempFolder, Constant.PluginMetadataFileName);
|
||||
if (!File.Exists(jsonPath))
|
||||
{
|
||||
MessageBox.Show("Install failed: plugin config is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
PluginMetadata plugin = GetMetadataFromJson(tempFoler);
|
||||
PluginMetadata plugin = GetMetadataFromJson(tempFolder);
|
||||
if (plugin == null || plugin.Name == null)
|
||||
{
|
||||
MessageBox.Show("Install failed: plugin config is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
string pluginFolerPath = Infrastructure.UserSettings.DataLocation.PluginsDirectory;
|
||||
string pluginFolderPath = Infrastructure.UserSettings.DataLocation.PluginsDirectory;
|
||||
|
||||
string newPluginName = plugin.Name
|
||||
.Replace("/", "_")
|
||||
|
|
@ -46,7 +48,9 @@ namespace Flow.Launcher.Core.Plugin
|
|||
.Replace("*", "_")
|
||||
.Replace("|", "_")
|
||||
+ "-" + Guid.NewGuid();
|
||||
string newPluginPath = Path.Combine(pluginFolerPath, newPluginName);
|
||||
|
||||
string newPluginPath = Path.Combine(pluginFolderPath, newPluginName);
|
||||
|
||||
string content = $"Do you want to install following plugin?{Environment.NewLine}{Environment.NewLine}" +
|
||||
$"Name: {plugin.Name}{Environment.NewLine}" +
|
||||
$"Version: {plugin.Version}{Environment.NewLine}" +
|
||||
|
|
@ -71,8 +75,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
File.Create(Path.Combine(existingPlugin.Metadata.PluginDirectory, "NeedDelete.txt")).Close();
|
||||
}
|
||||
|
||||
UnZip(path, newPluginPath, true);
|
||||
Directory.Delete(tempFoler, true);
|
||||
Directory.Move(tempFolder, newPluginPath);
|
||||
|
||||
//exsiting plugins may be has loaded by application,
|
||||
//if we try to delelte those kind of plugins, we will get a error that indicate the
|
||||
|
|
@ -94,7 +97,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
|
||||
private static PluginMetadata GetMetadataFromJson(string pluginDirectory)
|
||||
{
|
||||
string configPath = Path.Combine(pluginDirectory, "plugin.json");
|
||||
string configPath = Path.Combine(pluginDirectory, Constant.PluginMetadataFileName);
|
||||
PluginMetadata metadata;
|
||||
|
||||
if (!File.Exists(configPath))
|
||||
|
|
@ -107,36 +110,20 @@ namespace Flow.Launcher.Core.Plugin
|
|||
metadata = JsonConvert.DeserializeObject<PluginMetadata>(File.ReadAllText(configPath));
|
||||
metadata.PluginDirectory = pluginDirectory;
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
string error = $"Parse plugin config {configPath} failed: json format is not valid";
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw new Exception(error);
|
||||
}
|
||||
#endif
|
||||
Log.Exception($"|PluginInstaller.GetMetadataFromJson|plugin config {configPath} failed: invalid json format", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (!AllowedLanguage.IsAllowed(metadata.Language))
|
||||
{
|
||||
string error = $"Parse plugin config {configPath} failed: invalid language {metadata.Language}";
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw new Exception(error);
|
||||
}
|
||||
#endif
|
||||
Log.Error($"|PluginInstaller.GetMetadataFromJson|plugin config {configPath} failed: invalid language {metadata.Language}");
|
||||
return null;
|
||||
}
|
||||
if (!File.Exists(metadata.ExecuteFilePath))
|
||||
{
|
||||
string error = $"Parse plugin config {configPath} failed: ExecuteFile {metadata.ExecuteFilePath} didn't exist";
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw new Exception(error);
|
||||
}
|
||||
#endif
|
||||
Log.Error($"|PluginInstaller.GetMetadataFromJson|plugin config {configPath} failed: file {metadata.ExecuteFilePath} doesn't exist");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -144,58 +131,38 @@ namespace Flow.Launcher.Core.Plugin
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// unzip
|
||||
/// unzip plugin contents to the given directory.
|
||||
/// </summary>
|
||||
/// <param name="zipedFile">The ziped file.</param>
|
||||
/// <param name="strDirectory">The STR directory.</param>
|
||||
/// <param name="zipFile">The path to the zip file.</param>
|
||||
/// <param name="strDirectory">The output directory.</param>
|
||||
/// <param name="overWrite">overwirte</param>
|
||||
private static void UnZip(string zipedFile, string strDirectory, bool overWrite)
|
||||
private static void UnZip(string zipFile, string strDirectory, bool overWrite)
|
||||
{
|
||||
if (strDirectory == "")
|
||||
strDirectory = Directory.GetCurrentDirectory();
|
||||
if (!strDirectory.EndsWith("\\"))
|
||||
strDirectory = strDirectory + "\\";
|
||||
|
||||
using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipedFile)))
|
||||
using (ZipInputStream zipStream = new ZipInputStream(File.OpenRead(zipFile)))
|
||||
{
|
||||
ZipEntry theEntry;
|
||||
|
||||
while ((theEntry = s.GetNextEntry()) != null)
|
||||
while ((theEntry = zipStream.GetNextEntry()) != null)
|
||||
{
|
||||
string directoryName = "";
|
||||
string pathToZip = "";
|
||||
pathToZip = theEntry.Name;
|
||||
var pathToZip = theEntry.Name;
|
||||
var directoryName = String.IsNullOrEmpty(pathToZip) ? "" : Path.GetDirectoryName(pathToZip);
|
||||
var fileName = Path.GetFileName(pathToZip);
|
||||
var destinationDir = Path.Combine(strDirectory, directoryName);
|
||||
var destinationFile = Path.Combine(destinationDir, fileName);
|
||||
|
||||
if (pathToZip != "")
|
||||
directoryName = Path.GetDirectoryName(pathToZip) + "\\";
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
|
||||
string fileName = Path.GetFileName(pathToZip);
|
||||
if (String.IsNullOrEmpty(fileName) || (File.Exists(destinationFile) && !overWrite))
|
||||
continue;
|
||||
|
||||
Directory.CreateDirectory(strDirectory + directoryName);
|
||||
|
||||
if (fileName != "")
|
||||
using (FileStream streamWriter = File.Create(destinationFile))
|
||||
{
|
||||
if ((File.Exists(strDirectory + directoryName + fileName) && overWrite) || (!File.Exists(strDirectory + directoryName + fileName)))
|
||||
{
|
||||
using (FileStream streamWriter = File.Create(strDirectory + directoryName + fileName))
|
||||
{
|
||||
byte[] data = new byte[2048];
|
||||
while (true)
|
||||
{
|
||||
int size = s.Read(data, 0, data.Length);
|
||||
|
||||
if (size > 0)
|
||||
streamWriter.Write(data, 0, size);
|
||||
else
|
||||
break;
|
||||
}
|
||||
streamWriter.Close();
|
||||
}
|
||||
}
|
||||
zipStream.CopyTo(streamWriter);
|
||||
}
|
||||
}
|
||||
|
||||
s.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,6 @@ namespace Flow.Launcher.Core.Plugin
|
|||
{
|
||||
private static IEnumerable<PluginPair> _contextMenuPlugins;
|
||||
|
||||
/// <summary>
|
||||
/// Directories that will hold Flow Launcher plugin directory
|
||||
/// </summary>
|
||||
|
||||
public static List<PluginPair> AllPlugins { get; private set; }
|
||||
public static readonly List<PluginPair> GlobalPlugins = new List<PluginPair>();
|
||||
public static readonly Dictionary<string, PluginPair> NonGlobalPlugins = new Dictionary<string, PluginPair>();
|
||||
|
|
@ -32,27 +28,18 @@ namespace Flow.Launcher.Core.Plugin
|
|||
// todo happlebao, this should not be public, the indicator function should be embeded
|
||||
public static PluginsSettings Settings;
|
||||
private static List<PluginMetadata> _metadatas;
|
||||
private static readonly string[] Directories = { Constant.PreinstalledDirectory, DataLocation.PluginsDirectory };
|
||||
|
||||
private static void ValidateUserDirectory()
|
||||
{
|
||||
if (!Directory.Exists(DataLocation.PluginsDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(DataLocation.PluginsDirectory);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Directories that will hold Flow Launcher plugin directory
|
||||
/// </summary>
|
||||
private static readonly string[] Directories = { Constant.PreinstalledDirectory, DataLocation.PluginsDirectory };
|
||||
|
||||
private static void DeletePythonBinding()
|
||||
{
|
||||
const string binding = "flowlauncher.py";
|
||||
var directory = DataLocation.PluginsDirectory;
|
||||
foreach (var subDirectory in Directory.GetDirectories(directory))
|
||||
foreach (var subDirectory in Directory.GetDirectories(DataLocation.PluginsDirectory))
|
||||
{
|
||||
var path = Path.Combine(subDirectory, binding);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
File.Delete(Path.Combine(subDirectory, binding));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +63,8 @@ namespace Flow.Launcher.Core.Plugin
|
|||
|
||||
static PluginManager()
|
||||
{
|
||||
ValidateUserDirectory();
|
||||
// validate user directory
|
||||
Directory.CreateDirectory(DataLocation.PluginsDirectory);
|
||||
// force old plugins use new python binding
|
||||
DeletePythonBinding();
|
||||
}
|
||||
|
|
@ -132,9 +120,10 @@ namespace Flow.Launcher.Core.Plugin
|
|||
GlobalPlugins.Add(plugin);
|
||||
|
||||
// Plugins may have multiple ActionKeywords, eg. WebSearch
|
||||
plugin.Metadata.ActionKeywords.Where(x => x != Query.GlobalPluginWildcardSign)
|
||||
.ToList()
|
||||
.ForEach(x => NonGlobalPlugins[x] = plugin);
|
||||
plugin.Metadata.ActionKeywords
|
||||
.Where(x => x != Query.GlobalPluginWildcardSign)
|
||||
.ToList()
|
||||
.ForEach(x => NonGlobalPlugins[x] = plugin);
|
||||
}
|
||||
|
||||
if (failedPlugins.Any())
|
||||
|
|
@ -164,9 +153,9 @@ namespace Flow.Launcher.Core.Plugin
|
|||
|
||||
public static List<Result> QueryForPlugin(PluginPair pair, Query query)
|
||||
{
|
||||
var results = new List<Result>();
|
||||
try
|
||||
{
|
||||
List<Result> results = null;
|
||||
var metadata = pair.Metadata;
|
||||
var milliseconds = Stopwatch.Debug($"|PluginManager.QueryForPlugin|Cost for {metadata.Name}", () =>
|
||||
{
|
||||
|
|
@ -175,13 +164,12 @@ namespace Flow.Launcher.Core.Plugin
|
|||
});
|
||||
metadata.QueryCount += 1;
|
||||
metadata.AvgQueryTime = metadata.QueryCount == 1 ? milliseconds : (metadata.AvgQueryTime + milliseconds) / 2;
|
||||
return results;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Exception($"|PluginManager.QueryForPlugin|Exception for plugin <{pair.Metadata.Name}> when query <{query}>", e);
|
||||
return new List<Result>();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static void UpdatePluginMetadata(List<Result> results, PluginMetadata metadata, Query query)
|
||||
|
|
@ -221,47 +209,34 @@ namespace Flow.Launcher.Core.Plugin
|
|||
|
||||
public static List<Result> GetContextMenusForPlugin(Result result)
|
||||
{
|
||||
var results = new List<Result>();
|
||||
var pluginPair = _contextMenuPlugins.FirstOrDefault(o => o.Metadata.ID == result.PluginID);
|
||||
if (pluginPair != null)
|
||||
{
|
||||
var metadata = pluginPair.Metadata;
|
||||
var plugin = (IContextMenu)pluginPair.Plugin;
|
||||
|
||||
try
|
||||
{
|
||||
var results = plugin.LoadContextMenus(result);
|
||||
results = plugin.LoadContextMenus(result);
|
||||
foreach (var r in results)
|
||||
{
|
||||
r.PluginDirectory = metadata.PluginDirectory;
|
||||
r.PluginID = metadata.ID;
|
||||
r.PluginDirectory = pluginPair.Metadata.PluginDirectory;
|
||||
r.PluginID = pluginPair.Metadata.ID;
|
||||
r.OriginQuery = result.OriginQuery;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Exception($"|PluginManager.GetContextMenusForPlugin|Can't load context menus for plugin <{metadata.Name}>", e);
|
||||
return new List<Result>();
|
||||
Log.Exception($"|PluginManager.GetContextMenusForPlugin|Can't load context menus for plugin <{pluginPair.Metadata.Name}>", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<Result>();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static bool ActionKeywordRegistered(string actionKeyword)
|
||||
{
|
||||
if (actionKeyword != Query.GlobalPluginWildcardSign &&
|
||||
NonGlobalPlugins.ContainsKey(actionKeyword))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return actionKeyword != Query.GlobalPluginWildcardSign
|
||||
&& NonGlobalPlugins.ContainsKey(actionKeyword);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -299,7 +274,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
GlobalPlugins.Remove(plugin);
|
||||
}
|
||||
|
||||
if(oldActionkeyword != Query.GlobalPluginWildcardSign)
|
||||
if (oldActionkeyword != Query.GlobalPluginWildcardSign)
|
||||
NonGlobalPlugins.Remove(oldActionkeyword);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
|
||||
public static List<PluginPair> Plugins(List<PluginMetadata> metadatas, PluginsSettings settings)
|
||||
{
|
||||
var dotnetPlugins = DotNetPlugins(metadatas).ToList();
|
||||
var dotnetPlugins = DotNetPlugins(metadatas);
|
||||
var pythonPlugins = PythonPlugins(metadatas, settings.PythonDirectory);
|
||||
var executablePlugins = ExecutablePlugins(metadatas);
|
||||
var plugins = dotnetPlugins.Concat(pythonPlugins).Concat(executablePlugins).ToList();
|
||||
|
|
@ -46,75 +46,58 @@ namespace Flow.Launcher.Core.Plugin
|
|||
var type = types.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin)));
|
||||
var plugin = (IPlugin)Activator.CreateInstance(type);
|
||||
#else
|
||||
Assembly assembly;
|
||||
Assembly assembly = null;
|
||||
IPlugin plugin = null;
|
||||
|
||||
try
|
||||
{
|
||||
assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(metadata.ExecuteFilePath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
erroredPlugins.Add(metadata.Name);
|
||||
|
||||
Log.Exception($"|PluginsLoader.DotNetPlugins|Couldn't load assembly for the plugin: {metadata.Name}", e);
|
||||
return;
|
||||
}
|
||||
|
||||
Type type;
|
||||
try
|
||||
{
|
||||
var types = assembly.GetTypes();
|
||||
|
||||
type = types.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin)));
|
||||
var type = types.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin)));
|
||||
|
||||
plugin = (IPlugin)Activator.CreateInstance(type);
|
||||
}
|
||||
catch (Exception e) when (assembly == null)
|
||||
{
|
||||
Log.Exception($"|PluginsLoader.DotNetPlugins|Couldn't load assembly for the plugin: {metadata.Name}", e);
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
erroredPlugins.Add(metadata.Name);
|
||||
|
||||
Log.Exception($"|PluginsLoader.DotNetPlugins|Can't find the required IPlugin interface for the plugin: <{metadata.Name}>", e);
|
||||
return;
|
||||
}
|
||||
catch (ReflectionTypeLoadException e)
|
||||
{
|
||||
erroredPlugins.Add(metadata.Name);
|
||||
|
||||
Log.Exception($"|PluginsLoader.DotNetPlugins|The GetTypes method was unable to load assembly types for the plugin: <{metadata.Name}>", e);
|
||||
return;
|
||||
}
|
||||
|
||||
IPlugin plugin;
|
||||
try
|
||||
{
|
||||
plugin = (IPlugin)Activator.CreateInstance(type);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
erroredPlugins.Add(metadata.Name);
|
||||
|
||||
Log.Exception($"|PluginsLoader.DotNetPlugins|The following plugin has errored and can not be loaded: <{metadata.Name}>", e);
|
||||
}
|
||||
|
||||
if (plugin == null)
|
||||
{
|
||||
erroredPlugins.Add(metadata.Name);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
PluginPair pair = new PluginPair
|
||||
plugins.Add(new PluginPair
|
||||
{
|
||||
Plugin = plugin,
|
||||
Metadata = metadata
|
||||
};
|
||||
plugins.Add(pair);
|
||||
});
|
||||
});
|
||||
metadata.InitTime += milliseconds;
|
||||
|
||||
}
|
||||
|
||||
if (erroredPlugins.Count > 0)
|
||||
{
|
||||
var errorPluginString = "";
|
||||
var errorPluginString = String.Join(Environment.NewLine, erroredPlugins);
|
||||
|
||||
var errorMessage = "The following "
|
||||
+ (erroredPlugins.Count > 1 ? "plugins have " : "plugin has ")
|
||||
+ "errored and cannot be loaded:";
|
||||
|
||||
erroredPlugins.ForEach(x => errorPluginString += x + Environment.NewLine);
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
MessageBox.Show($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
|
||||
|
|
@ -127,65 +110,74 @@ namespace Flow.Launcher.Core.Plugin
|
|||
return plugins;
|
||||
}
|
||||
|
||||
public static IEnumerable<PluginPair> PythonPlugins(List<PluginMetadata> source, string pythonDirecotry)
|
||||
public static IEnumerable<PluginPair> PythonPlugins(List<PluginMetadata> source, string pythonDirectory)
|
||||
{
|
||||
var metadatas = source.Where(o => o.Language.ToUpper() == AllowedLanguage.Python);
|
||||
string filename;
|
||||
|
||||
if (string.IsNullOrEmpty(pythonDirecotry))
|
||||
// try to set Constant.PythonPath, either from
|
||||
// PATH or from the given pythonDirectory
|
||||
if (string.IsNullOrEmpty(pythonDirectory))
|
||||
{
|
||||
var paths = Environment.GetEnvironmentVariable(PATH);
|
||||
if (paths != null)
|
||||
{
|
||||
var pythonPaths = paths.Split(';').Where(p => p.ToLower().Contains(Python));
|
||||
if (pythonPaths.Any())
|
||||
var pythonInPath = paths
|
||||
.Split(';')
|
||||
.Where(p => p.ToLower().Contains(Python))
|
||||
.Any();
|
||||
|
||||
if (pythonInPath)
|
||||
{
|
||||
filename = PythonExecutable;
|
||||
Constant.PythonPath = PythonExecutable;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("|PluginsLoader.PythonPlugins|Python can't be found in PATH.");
|
||||
return new List<PluginPair>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("|PluginsLoader.PythonPlugins|PATH environment variable is not set.");
|
||||
return new List<PluginPair>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var path = Path.Combine(pythonDirecotry, PythonExecutable);
|
||||
var path = Path.Combine(pythonDirectory, PythonExecutable);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
filename = path;
|
||||
Constant.PythonPath = path;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("|PluginsLoader.PythonPlugins|Can't find python executable in <b ");
|
||||
return new List<PluginPair>();
|
||||
Log.Error($"|PluginsLoader.PythonPlugins|Can't find python executable in {path}");
|
||||
}
|
||||
}
|
||||
Constant.PythonPath = filename;
|
||||
var plugins = metadatas.Select(metadata => new PluginPair
|
||||
|
||||
// if we have a path to the python executable,
|
||||
// load every python plugin pair.
|
||||
if (String.IsNullOrEmpty(Constant.PythonPath))
|
||||
{
|
||||
Plugin = new PythonPlugin(filename),
|
||||
Metadata = metadata
|
||||
});
|
||||
return plugins;
|
||||
return new List<PluginPair>();
|
||||
}
|
||||
else
|
||||
{
|
||||
return source
|
||||
.Where(o => o.Language.ToUpper() == AllowedLanguage.Python)
|
||||
.Select(metadata => new PluginPair
|
||||
{
|
||||
Plugin = new PythonPlugin(Constant.PythonPath),
|
||||
Metadata = metadata
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<PluginPair> ExecutablePlugins(IEnumerable<PluginMetadata> source)
|
||||
{
|
||||
var metadatas = source.Where(o => o.Language.ToUpper() == AllowedLanguage.Executable);
|
||||
|
||||
var plugins = metadatas.Select(metadata => new PluginPair
|
||||
{
|
||||
Plugin = new ExecutablePlugin(metadata.ExecuteFilePath),
|
||||
Metadata = metadata
|
||||
});
|
||||
return plugins;
|
||||
return source
|
||||
.Where(o => o.Language.ToUpper() == AllowedLanguage.Executable)
|
||||
.Select(metadata => new PluginPair
|
||||
{
|
||||
Plugin = new ExecutablePlugin(metadata.ExecuteFilePath),
|
||||
Metadata = metadata
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ namespace Flow.Launcher.Core
|
|||
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
|
||||
FilesFolders.Copy(DataLocation.PortableDataPath, targetDestination);
|
||||
if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination))
|
||||
MessageBox.Show(string.Format("Flow Launcher was not able to move your user profile data to the new update version. Please manually" +
|
||||
"move your profile data folder from {0} to {1}", 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}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB |
|
|
@ -8,6 +8,7 @@ namespace Flow.Launcher.Infrastructure
|
|||
{
|
||||
public const string FlowLauncher = "Flow.Launcher";
|
||||
public const string Plugins = "Plugins";
|
||||
public const string PluginMetadataFileName = "plugin.json";
|
||||
|
||||
public const string ApplicationFileName = FlowLauncher + ".exe";
|
||||
|
||||
|
|
|
|||
|
|
@ -83,9 +83,18 @@ namespace Flow.Launcher.Infrastructure
|
|||
bool allSubstringsContainedInCompareString = true;
|
||||
|
||||
var indexList = new List<int>();
|
||||
List<int> spaceIndices = new List<int>();
|
||||
|
||||
for (var compareStringIndex = 0; compareStringIndex < fullStringToCompareWithoutCase.Length; compareStringIndex++)
|
||||
{
|
||||
|
||||
// To maintain a list of indices which correspond to spaces in the string to compare
|
||||
// To populate the list only for the first query substring
|
||||
if (fullStringToCompareWithoutCase[compareStringIndex].Equals(' ') && currentQuerySubstringIndex == 0)
|
||||
{
|
||||
spaceIndices.Add(compareStringIndex);
|
||||
}
|
||||
|
||||
if (fullStringToCompareWithoutCase[compareStringIndex] != currentQuerySubstring[currentQuerySubstringCharacterIndex])
|
||||
{
|
||||
matchFoundInPreviousLoop = false;
|
||||
|
|
@ -147,15 +156,31 @@ namespace Flow.Launcher.Infrastructure
|
|||
// proceed to calculate score if every char or substring without whitespaces matched
|
||||
if (allQuerySubstringsMatched)
|
||||
{
|
||||
var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex, lastMatchIndex - firstMatchIndex, allSubstringsContainedInCompareString);
|
||||
var nearestSpaceIndex = CalculateClosestSpaceIndex(spaceIndices, firstMatchIndex);
|
||||
var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex - nearestSpaceIndex - 1, lastMatchIndex - firstMatchIndex, allSubstringsContainedInCompareString);
|
||||
|
||||
return new MatchResult(true, UserSettingSearchPrecision, indexList, score);
|
||||
}
|
||||
|
||||
return new MatchResult (false, UserSettingSearchPrecision);
|
||||
return new MatchResult(false, UserSettingSearchPrecision);
|
||||
}
|
||||
|
||||
private static bool AllPreviousCharsMatched(int startIndexToVerify, int currentQuerySubstringCharacterIndex,
|
||||
// To get the index of the closest space which preceeds the first matching index
|
||||
private int CalculateClosestSpaceIndex(List<int> spaceIndices, int firstMatchIndex)
|
||||
{
|
||||
if (spaceIndices.Count == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int? ind = spaceIndices.OrderBy(item => (firstMatchIndex - item)).Where(item => firstMatchIndex > item).FirstOrDefault();
|
||||
int closestSpaceIndex = ind ?? -1;
|
||||
return closestSpaceIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool AllPreviousCharsMatched(int startIndexToVerify, int currentQuerySubstringCharacterIndex,
|
||||
string fullStringToCompareWithoutCase, string currentQuerySubstring)
|
||||
{
|
||||
var allMatch = true;
|
||||
|
|
@ -299,13 +324,13 @@ namespace Flow.Launcher.Infrastructure
|
|||
public class MatchOption
|
||||
{
|
||||
/// <summary>
|
||||
/// prefix of match char, use for hightlight
|
||||
/// 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 hightlight
|
||||
/// suffix of match char, use for highlight
|
||||
/// </summary>
|
||||
[Obsolete("this is never used")]
|
||||
public string Suffix { get; set; } = "";
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Version>1.0.0</Version>
|
||||
<PackageVersion>1.0.0-beta3</PackageVersion>
|
||||
<PackageVersion>1.0.0</PackageVersion>
|
||||
<AssemblyVersion>1.0.0</AssemblyVersion>
|
||||
<FileVersion>1.0.0</FileVersion>
|
||||
<PackageId>Flow.Launcher.Plugin</PackageId>
|
||||
|
|
|
|||
|
|
@ -130,5 +130,15 @@ namespace Flow.Launcher.Plugin
|
|||
/// Plugin ID that generated this result
|
||||
/// </summary>
|
||||
public string PluginID { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Show message as ToolTip on result Title hover over
|
||||
/// </summary>
|
||||
public string TitleToolTip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Show message as ToolTip on result SubTitle hover over
|
||||
/// </summary>
|
||||
public string SubTitleToolTip { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,9 @@ namespace Flow.Launcher.Plugin.SharedCommands
|
|||
public static class FilesFolders
|
||||
{
|
||||
private const string FileExplorerProgramName = "explorer";
|
||||
|
||||
private const string FileExplorerProgramEXE = "explorer.exe";
|
||||
|
||||
public static void Copy(this string sourcePath, string targetPath)
|
||||
{
|
||||
// Get the subdirectories for the specified directory.
|
||||
|
|
@ -128,6 +131,11 @@ namespace Flow.Launcher.Plugin.SharedCommands
|
|||
}
|
||||
}
|
||||
|
||||
public static void OpenContainingFolder(string path)
|
||||
{
|
||||
Process.Start(FileExplorerProgramEXE, $" /select,\"{path}\"");
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// This checks whether a given string is a directory path or network location string.
|
||||
/// It does not check if location actually exists.
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ namespace Flow.Launcher.Test
|
|||
}
|
||||
|
||||
[TestCase("Chrome")]
|
||||
public void WhenGivenNotAllCharactersFoundInSearchStringThenShouldReturnZeroScore(string searchString)
|
||||
public void WhenNotAllCharactersFoundInSearchString_ThenShouldReturnZeroScore(string searchString)
|
||||
{
|
||||
var compareString = "Can have rum only in my glass";
|
||||
var matcher = new StringMatcher();
|
||||
|
|
@ -92,7 +92,7 @@ namespace Flow.Launcher.Test
|
|||
[TestCase("cand")]
|
||||
[TestCase("cpywa")]
|
||||
[TestCase("ccs")]
|
||||
public void WhenGivenStringsAndAppliedPrecisionFilteringThenShouldReturnGreaterThanPrecisionScoreResults(string searchTerm)
|
||||
public void GivenQueryString_WhenAppliedPrecisionFiltering_ThenShouldReturnGreaterThanPrecisionScoreResults(string searchTerm)
|
||||
{
|
||||
var results = new List<Result>();
|
||||
var matcher = new StringMatcher();
|
||||
|
|
@ -107,7 +107,10 @@ namespace Flow.Launcher.Test
|
|||
|
||||
foreach (var precisionScore in GetPrecisionScores())
|
||||
{
|
||||
var filteredResult = results.Where(result => result.Score >= precisionScore).Select(result => result).OrderByDescending(x => x.Score).ToList();
|
||||
var filteredResult = results.Where(result => result.Score >= precisionScore)
|
||||
.Select(result => result)
|
||||
.OrderByDescending(x => x.Score)
|
||||
.ToList();
|
||||
|
||||
Debug.WriteLine("");
|
||||
Debug.WriteLine("###############################################");
|
||||
|
|
@ -124,20 +127,22 @@ namespace Flow.Launcher.Test
|
|||
}
|
||||
|
||||
[TestCase(Chrome, Chrome, 157)]
|
||||
[TestCase(Chrome, LastIsChrome, 103)]
|
||||
[TestCase(Chrome, HelpCureHopeRaiseOnMindEntityChrome, 21)]
|
||||
[TestCase(Chrome, UninstallOrChangeProgramsOnYourComputer, 15)]
|
||||
[TestCase(Chrome, LastIsChrome, 147)]
|
||||
[TestCase(Chrome, HelpCureHopeRaiseOnMindEntityChrome, 25)]
|
||||
[TestCase(Chrome, UninstallOrChangeProgramsOnYourComputer, 21)]
|
||||
[TestCase(Chrome, CandyCrushSagaFromKing, 0)]
|
||||
[TestCase("sql", MicrosoftSqlServerManagementStudio, 56)]
|
||||
[TestCase("sql manag", MicrosoftSqlServerManagementStudio, 99)]//double spacing intended
|
||||
public void WhenGivenQueryStringThenShouldReturnCurrentScoring(string queryString, string compareString, int expectedScore)
|
||||
[TestCase("sql", MicrosoftSqlServerManagementStudio, 110)]
|
||||
[TestCase("sql manag", MicrosoftSqlServerManagementStudio, 121)]//double spacing intended
|
||||
public void WhenGivenQueryString_ThenShouldReturn_TheDesiredScoring(
|
||||
string queryString, string compareString, int expectedScore)
|
||||
{
|
||||
// When, Given
|
||||
var matcher = new StringMatcher();
|
||||
var rawScore = matcher.FuzzyMatch(queryString, compareString).RawScore;
|
||||
|
||||
// Should
|
||||
Assert.AreEqual(expectedScore, rawScore, $"Expected score for compare string '{compareString}': {expectedScore}, Actual: {rawScore}");
|
||||
Assert.AreEqual(expectedScore, rawScore,
|
||||
$"Expected score for compare string '{compareString}': {expectedScore}, Actual: {rawScore}");
|
||||
}
|
||||
|
||||
[TestCase("goo", "Google Chrome", StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
|
|
@ -150,7 +155,7 @@ namespace Flow.Launcher.Test
|
|||
[TestCase("ccs", "Candy Crush Saga from King", StringMatcher.SearchPrecisionScore.Low, true)]
|
||||
[TestCase("cand", "Candy Crush Saga from King",StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
[TestCase("cand", "Help cure hope raise on mind entity Chrome", StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||
public void WhenGivenDesiredPrecisionThenShouldReturnAllResultsGreaterOrEqual(
|
||||
public void WhenGivenDesiredPrecision_ThenShouldReturn_AllResultsGreaterOrEqual(
|
||||
string queryString,
|
||||
string compareString,
|
||||
StringMatcher.SearchPrecisionScore expectedPrecisionScore,
|
||||
|
|
@ -185,8 +190,8 @@ namespace Flow.Launcher.Test
|
|||
[TestCase("sql manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
[TestCase("sql", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
[TestCase("sql serv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
[TestCase("sqlserv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||
[TestCase("sql servman", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||
[TestCase("servez", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||
[TestCase("sql servz", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
|
||||
[TestCase("sql serv man", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
[TestCase("sql studio", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
[TestCase("mic", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
|
|
@ -199,7 +204,7 @@ namespace Flow.Launcher.Test
|
|||
[TestCase("cod", VisualStudioCode, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
[TestCase("code", VisualStudioCode, StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
[TestCase("codes", "Visual Studio Codes", StringMatcher.SearchPrecisionScore.Regular, true)]
|
||||
public void WhenGivenQueryShouldReturnResultsContainingAllQuerySubstrings(
|
||||
public void WhenGivenQuery_ShouldReturnResults_ContainingAllQuerySubstrings(
|
||||
string queryString,
|
||||
string compareString,
|
||||
StringMatcher.SearchPrecisionScore expectedPrecisionScore,
|
||||
|
|
@ -225,5 +230,60 @@ namespace Flow.Launcher.Test
|
|||
$"Raw Score: {matchResult.RawScore}{Environment.NewLine}" +
|
||||
$"Precision Score: {(int)expectedPrecisionScore}");
|
||||
}
|
||||
|
||||
[TestCase("man", "Task Manager", "eManual")]
|
||||
[TestCase("term", "Windows Terminal", "Character Map")]
|
||||
[TestCase("winterm", "Windows Terminal", "Cygwin64 Terminal")]
|
||||
public void WhenGivenAQuery_Scoring_ShouldGiveMoreWeightToStartOfNewWord(
|
||||
string queryString, string compareString1, string compareString2)
|
||||
{
|
||||
// When
|
||||
var matcher = new StringMatcher { UserSettingSearchPrecision = StringMatcher.SearchPrecisionScore.Regular };
|
||||
|
||||
// Given
|
||||
var compareString1Result = matcher.FuzzyMatch(queryString, compareString1);
|
||||
var compareString2Result = matcher.FuzzyMatch(queryString, compareString2);
|
||||
|
||||
Debug.WriteLine("");
|
||||
Debug.WriteLine("###############################################");
|
||||
Debug.WriteLine($"QueryString: \"{queryString}\"{Environment.NewLine}");
|
||||
Debug.WriteLine($"CompareString1: \"{compareString1}\", Score: {compareString1Result.Score}{Environment.NewLine}");
|
||||
Debug.WriteLine($"CompareString2: \"{compareString2}\", Score: {compareString2Result.Score}{Environment.NewLine}");
|
||||
Debug.WriteLine("###############################################");
|
||||
Debug.WriteLine("");
|
||||
|
||||
// Should
|
||||
Assert.True(compareString1Result.Score > compareString2Result.Score,
|
||||
$"Query: \"{queryString}\"{Environment.NewLine} " +
|
||||
$"CompareString1: \"{compareString1}\", Score: {compareString1Result.Score}{Environment.NewLine}" +
|
||||
$"Should be greater than{ Environment.NewLine}" +
|
||||
$"CompareString2: \"{compareString2}\", Score: {compareString1Result.Score}{Environment.NewLine}");
|
||||
}
|
||||
|
||||
[TestCase("vim", "Vim", "ignoreDescription", "ignore.exe", "Vim Diff", "ignoreDescription", "ignore.exe")]
|
||||
public void WhenMultipleResults_ExactMatchingResult_ShouldHaveGreatestScore(
|
||||
string queryString, string firstName, string firstDescription, string firstExecutableName,
|
||||
string secondName, string secondDescription, string secondExecutableName)
|
||||
{
|
||||
// Act
|
||||
var matcher = new StringMatcher();
|
||||
var firstNameMatch = matcher.FuzzyMatch(queryString, firstName).RawScore;
|
||||
var firstDescriptionMatch = matcher.FuzzyMatch(queryString, firstDescription).RawScore;
|
||||
var firstExecutableNameMatch = matcher.FuzzyMatch(queryString, firstExecutableName).RawScore;
|
||||
|
||||
var secondNameMatch = matcher.FuzzyMatch(queryString, secondName).RawScore;
|
||||
var secondDescriptionMatch = matcher.FuzzyMatch(queryString, secondDescription).RawScore;
|
||||
var secondExecutableNameMatch = matcher.FuzzyMatch(queryString, secondExecutableName).RawScore;
|
||||
|
||||
var firstScore = new[] { firstNameMatch, firstDescriptionMatch, firstExecutableNameMatch }.Max();
|
||||
var secondScore = new[] { secondNameMatch, secondDescriptionMatch, secondExecutableNameMatch }.Max();
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(firstScore > secondScore,
|
||||
$"Query: \"{queryString}\"{Environment.NewLine} " +
|
||||
$"Name of first: \"{firstName}\", Final Score: {firstScore}{Environment.NewLine}" +
|
||||
$"Should be greater than{ Environment.NewLine}" +
|
||||
$"Name of second: \"{secondName}\", Final Score: {secondScore}{Environment.NewLine}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -62,16 +62,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
SolutionAssemblyInfo.cs = SolutionAssemblyInfo.cs
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorldCSharp", "Plugins\HelloWorldCSharp\HelloWorldCSharp.csproj", "{03FFA443-5F50-48D5-8869-F3DF316803AA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Shell", "Plugins\Flow.Launcher.Plugin.Shell\Flow.Launcher.Plugin.Shell.csproj", "{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.BrowserBookmark", "Plugins\Flow.Launcher.Plugin.BrowserBookmark\Flow.Launcher.Plugin.BrowserBookmark.csproj", "{9B130CC5-14FB-41FF-B310-0A95B6894C37}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Calculator", "Plugins\Flow.Launcher.Plugin.Calculator\Flow.Launcher.Plugin.Calculator.csproj", "{59BD9891-3837-438A-958D-ADC7F91F6F7E}"
|
||||
EndProject
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "HelloWorldFSharp", "Plugins\HelloWorldFSharp\HelloWorldFSharp.fsproj", "{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Explorer", "Plugins\Flow.Launcher.Plugin.Explorer\Flow.Launcher.Plugin.Explorer.csproj", "{F9C4C081-4CC3-4146-95F1-E102B4E10A5F}"
|
||||
EndProject
|
||||
Global
|
||||
|
|
@ -253,18 +249,6 @@ Global
|
|||
{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
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|x64.Build.0 = Release|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA}.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
|
||||
|
|
@ -301,18 +285,6 @@ Global
|
|||
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F9C4C081-4CC3-4146-95F1-E102B4E10A5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F9C4C081-4CC3-4146-95F1-E102B4E10A5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F9C4C081-4CC3-4146-95F1-E102B4E10A5F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -339,11 +311,9 @@ Global
|
|||
{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}
|
||||
{03FFA443-5F50-48D5-8869-F3DF316803AA} = {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}
|
||||
{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
|
||||
{F9C4C081-4CC3-4146-95F1-E102B4E10A5F} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Window x:Class="Flow.Launcher.ActionKeywords"
|
||||
<Window x:Class="Flow.Launcher.ActionKeywords"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="ActionKeywords"
|
||||
|
|
@ -6,38 +6,36 @@
|
|||
ResizeMode="NoResize"
|
||||
Loaded="ActionKeyword_OnLoaded"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Height="200" Width="600">
|
||||
Height="250" Width="500">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="60"/>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="170" />
|
||||
<ColumnDefinition Width="150" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Margin="10" FontSize="14" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right" Text="{DynamicResource oldActionKeyword}" />
|
||||
<TextBlock x:Name="tbOldActionKeyword" Margin="10" FontSize="14" Grid.Row="0" Grid.Column="1"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Left">
|
||||
Old ActionKeywords:
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock Margin="10" FontSize="14" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right" Text="{DynamicResource newActionKeyword}" />
|
||||
<TextBlock FontSize="14" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left" Text="{DynamicResource currentActionKeywords}" />
|
||||
<TextBlock x:Name="tbOldActionKeyword" Grid.Row="0" Grid.Column="1" Margin="170 10 10 10" FontSize="14"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock FontSize="14" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left" Text="{DynamicResource newActionKeyword}" />
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Grid.Column="1">
|
||||
<TextBox x:Name="tbAction" Margin="10" Width="400" VerticalAlignment="Center" HorizontalAlignment="Left" />
|
||||
<TextBox x:Name="tbAction" Margin="170 10 15 10" Width="105" VerticalAlignment="Center" HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.ColumnSpan="1" Grid.Column="1" Padding="5" Foreground="Gray"
|
||||
<TextBlock Grid.Row="2" Grid.ColumnSpan="1" Grid.Column="1" Foreground="Gray"
|
||||
Text="{DynamicResource actionkeyword_tips}" />
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="3" Grid.Column="1">
|
||||
<Button x:Name="btnCancel" Click="BtnCancel_OnClick" Margin="10 0 10 0" Width="80" Height="25"
|
||||
<Button x:Name="btnCancel" Click="BtnCancel_OnClick" Margin="10 0 10 0" Width="80" Height="30"
|
||||
Content="{DynamicResource cancel}" />
|
||||
<Button x:Name="btnDone" Margin="10 0 10 0" Width="80" Height="25" Click="btnDone_OnClick">
|
||||
<Button x:Name="btnDone" Margin="10 0 10 0" Width="80" Height="30" Click="btnDone_OnClick">
|
||||
<TextBlock x:Name="lblAdd" Text="{DynamicResource done}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
|
|
|||
|
|
@ -4,30 +4,33 @@ using Flow.Launcher.Core.Resource;
|
|||
using Flow.Launcher.Infrastructure.Exception;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
using Flow.Launcher.Plugin;
|
||||
using Flow.Launcher.ViewModel;
|
||||
|
||||
namespace Flow.Launcher
|
||||
{
|
||||
public partial class ActionKeywords : Window
|
||||
{
|
||||
private PluginPair _plugin;
|
||||
private Settings _settings;
|
||||
private readonly Internationalization _translater = InternationalizationManager.Instance;
|
||||
private readonly PluginPair plugin;
|
||||
private Settings settings;
|
||||
private readonly Internationalization translater = InternationalizationManager.Instance;
|
||||
private readonly PluginViewModel pluginViewModel;
|
||||
|
||||
public ActionKeywords(string pluginId, Settings settings)
|
||||
public ActionKeywords(string pluginId, Settings settings, PluginViewModel pluginViewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
_plugin = PluginManager.GetPluginForId(pluginId);
|
||||
_settings = settings;
|
||||
if (_plugin == null)
|
||||
plugin = PluginManager.GetPluginForId(pluginId);
|
||||
this.settings = settings;
|
||||
this.pluginViewModel = pluginViewModel;
|
||||
if (plugin == null)
|
||||
{
|
||||
MessageBox.Show(_translater.GetTranslation("cannotFindSpecifiedPlugin"));
|
||||
MessageBox.Show(translater.GetTranslation("cannotFindSpecifiedPlugin"));
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void ActionKeyword_OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeperater, _plugin.Metadata.ActionKeywords.ToArray());
|
||||
tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeperater, plugin.Metadata.ActionKeywords.ToArray());
|
||||
tbAction.Focus();
|
||||
}
|
||||
|
||||
|
|
@ -38,19 +41,17 @@ namespace Flow.Launcher
|
|||
|
||||
private void btnDone_OnClick(object sender, RoutedEventArgs _)
|
||||
{
|
||||
var oldActionKeyword = _plugin.Metadata.ActionKeywords[0];
|
||||
var oldActionKeyword = plugin.Metadata.ActionKeywords[0];
|
||||
var newActionKeyword = tbAction.Text.Trim();
|
||||
newActionKeyword = newActionKeyword.Length > 0 ? newActionKeyword : "*";
|
||||
if (!PluginManager.ActionKeywordRegistered(newActionKeyword))
|
||||
if (!pluginViewModel.IsActionKeywordRegistered(newActionKeyword))
|
||||
{
|
||||
var id = _plugin.Metadata.ID;
|
||||
PluginManager.ReplaceActionKeyword(id, oldActionKeyword, newActionKeyword);
|
||||
MessageBox.Show(_translater.GetTranslation("success"));
|
||||
pluginViewModel.ChangeActionKeyword(newActionKeyword, oldActionKeyword);
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
string msg = _translater.GetTranslation("newActionKeywordsHasBeenAssigned");
|
||||
string msg = translater.GetTranslation("newActionKeywordsHasBeenAssigned");
|
||||
MessageBox.Show(msg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Window x:Class="Flow.Launcher.CustomQueryHotkeySetting"
|
||||
<Window x:Class="Flow.Launcher.CustomQueryHotkeySetting"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:flowlauncher="clr-namespace:Flow.Launcher"
|
||||
|
|
@ -6,6 +6,12 @@
|
|||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="Custom Plugin Hotkey" Height="200" Width="674.766">
|
||||
<Window.InputBindings>
|
||||
<KeyBinding Key="Escape" Command="Close"/>
|
||||
</Window.InputBindings>
|
||||
<Window.CommandBindings>
|
||||
<CommandBinding Command="Close" Executed="cmdEsc_OnPress"/>
|
||||
</Window.CommandBindings>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
|
|
@ -18,7 +24,7 @@
|
|||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Margin="10" FontSize="14" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right" Text="{DynamicResource hotkey}" />
|
||||
<flowlauncher:HotkeyControl x:Name="ctlHotkey" Margin="10" Grid.Column="1" />
|
||||
<flowlauncher:HotkeyControl x:Name="ctlHotkey" Margin="10,0,10,0" Grid.Column="1" VerticalAlignment="Center" Height="32" />
|
||||
|
||||
<TextBlock Margin="10" FontSize="14" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right" Text="{DynamicResource actionKeyword}" />
|
||||
|
|
@ -29,9 +35,9 @@
|
|||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="2" Grid.Column="1">
|
||||
<Button x:Name="btnCancel" Click="BtnCancel_OnClick" Margin="10 0 10 0" Width="80" Height="25"
|
||||
<Button x:Name="btnCancel" Click="BtnCancel_OnClick" Margin="10 0 10 0" Width="80" Height="32"
|
||||
Content="{DynamicResource cancel}" />
|
||||
<Button x:Name="btnAdd" Margin="10 0 10 0" Width="80" Height="25" Click="btnAdd_OnClick">
|
||||
<Button x:Name="btnAdd" Margin="10 0 10 0" Width="80" Height="32" Click="btnAdd_OnClick">
|
||||
<TextBlock x:Name="lblAdd" Text="{DynamicResource done}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Flow.Launcher.Core.Resource;
|
||||
using Flow.Launcher.Infrastructure.Hotkey;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
using NHotkey;
|
||||
using NHotkey.Wpf;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using NHotkey;
|
||||
using NHotkey.Wpf;
|
||||
using Flow.Launcher.Core.Resource;
|
||||
using Flow.Launcher.Infrastructure.Hotkey;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Flow.Launcher
|
||||
{
|
||||
|
|
@ -125,5 +125,10 @@ namespace Flow.Launcher
|
|||
MessageBox.Show(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB |
|
|
@ -36,8 +36,8 @@
|
|||
<system:String x:Key="actionKeywords">Nøgleord</system:String>
|
||||
<system:String x:Key="pluginDirectory">Plugin bibliotek</system:String>
|
||||
<system:String x:Key="author">Forfatter</system:String>
|
||||
<system:String x:Key="plugin_init_time">Initaliseringstid: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Søgetid: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Initaliseringstid:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Søgetid:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Tema</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -36,8 +36,8 @@
|
|||
<system:String x:Key="actionKeywords">Aktionsschlüsselwörter</system:String>
|
||||
<system:String x:Key="pluginDirectory">Pluginordner</system:String>
|
||||
<system:String x:Key="author">Autor</system:String>
|
||||
<system:String x:Key="plugin_init_time">Initialisierungszeit: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Abfragezeit: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Initialisierungszeit:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Abfragezeit:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Theme</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -40,11 +40,13 @@
|
|||
<system:String x:Key="plugin">Plugin</system:String>
|
||||
<system:String x:Key="browserMorePlugins">Find more plugins</system:String>
|
||||
<system:String x:Key="disable">Disable</system:String>
|
||||
<system:String x:Key="actionKeywords">Action keywords</system:String>
|
||||
<system:String x:Key="actionKeywords">Action keyword:</system:String>
|
||||
<system:String x:Key="currentActionKeywords">Current action keyword:</system:String>
|
||||
<system:String x:Key="newActionKeyword">New action keyword:</system:String>
|
||||
<system:String x:Key="pluginDirectory">Plugin Directory</system:String>
|
||||
<system:String x:Key="author">Author</system:String>
|
||||
<system:String x:Key="plugin_init_time">Init time: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Query time: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Init time:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Query time:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Theme</system:String>
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@
|
|||
<system:String x:Key="actionKeywords">Mot-clé d'action :</system:String>
|
||||
<system:String x:Key="pluginDirectory">Répertoire</system:String>
|
||||
<system:String x:Key="author">Auteur </system:String>
|
||||
<system:String x:Key="plugin_init_time">Chargement : {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Utilisation : {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Chargement :</system:String>
|
||||
<system:String x:Key="plugin_query_time">Utilisation :</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Thèmes</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -40,8 +40,8 @@
|
|||
<system:String x:Key="actionKeywords">Parole chiave</system:String>
|
||||
<system:String x:Key="pluginDirectory">Cartella Plugin</system:String>
|
||||
<system:String x:Key="author">Autore</system:String>
|
||||
<system:String x:Key="plugin_init_time">Tempo di avvio: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Tempo ricerca: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Tempo di avvio:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Tempo ricerca:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Tema</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -41,8 +41,8 @@
|
|||
<system:String x:Key="actionKeywords">キーワード</system:String>
|
||||
<system:String x:Key="pluginDirectory">プラグイン・ディレクトリ</system:String>
|
||||
<system:String x:Key="author">作者</system:String>
|
||||
<system:String x:Key="plugin_init_time">初期化時間: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">クエリ時間: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">初期化時間:</system:String>
|
||||
<system:String x:Key="plugin_query_time">クエリ時間:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">テーマ</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -40,8 +40,8 @@
|
|||
<system:String x:Key="actionKeywords">액션 키워드</system:String>
|
||||
<system:String x:Key="pluginDirectory">플러그인 디렉토리</system:String>
|
||||
<system:String x:Key="author">저자</system:String>
|
||||
<system:String x:Key="plugin_init_time">초기화 시간: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">쿼리 시간: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">초기화 시간:</system:String>
|
||||
<system:String x:Key="plugin_query_time">쿼리 시간:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">테마</system:String>
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@
|
|||
<system:String x:Key="actionKeywords">Handlingsnøkkelord</system:String>
|
||||
<system:String x:Key="pluginDirectory">Utvidelseskatalog</system:String>
|
||||
<system:String x:Key="author">Forfatter</system:String>
|
||||
<system:String x:Key="plugin_init_time">Oppstartstid: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Spørringstid: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Oppstartstid:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Spørringstid:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Tema</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -36,8 +36,8 @@
|
|||
<system:String x:Key="actionKeywords">Action terfwoorden</system:String>
|
||||
<system:String x:Key="pluginDirectory">Plugin map</system:String>
|
||||
<system:String x:Key="author">Auteur</system:String>
|
||||
<system:String x:Key="plugin_init_time">Init tijd: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Query tijd: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Init tijd:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Query tijd:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Thema</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -36,8 +36,8 @@
|
|||
<system:String x:Key="actionKeywords">Wyzwalacze</system:String>
|
||||
<system:String x:Key="pluginDirectory">Folder wtyczki</system:String>
|
||||
<system:String x:Key="author">Autor</system:String>
|
||||
<system:String x:Key="plugin_init_time">Czas ładowania: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Czas zapytania: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Czas ładowania:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Czas zapytania:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Skórka</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -40,8 +40,8 @@
|
|||
<system:String x:Key="actionKeywords">Palavras-chave de ação</system:String>
|
||||
<system:String x:Key="pluginDirectory">Diretório de Plugins</system:String>
|
||||
<system:String x:Key="author">Autor</system:String>
|
||||
<system:String x:Key="plugin_init_time">Tempo de inicialização: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Tempo de consulta: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Tempo de inicialização:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Tempo de consulta:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Tema</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -36,8 +36,8 @@
|
|||
<system:String x:Key="actionKeywords">Ключевое слово</system:String>
|
||||
<system:String x:Key="pluginDirectory">Папка</system:String>
|
||||
<system:String x:Key="author">Автор</system:String>
|
||||
<system:String x:Key="plugin_init_time">Инициализация: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Запрос: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Инициализация:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Запрос:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Темы</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -41,8 +41,8 @@
|
|||
<system:String x:Key="actionKeywords">Skratka akcie</system:String>
|
||||
<system:String x:Key="pluginDirectory">Priečinok s pluginmy</system:String>
|
||||
<system:String x:Key="author">Autor</system:String>
|
||||
<system:String x:Key="plugin_init_time">Čas inic.: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Čas dopytu: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Čas inic.:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Čas dopytu:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Motív</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -40,8 +40,8 @@
|
|||
<system:String x:Key="actionKeywords">Ključne reči</system:String>
|
||||
<system:String x:Key="pluginDirectory">Plugin direktorijum</system:String>
|
||||
<system:String x:Key="author">Autor</system:String>
|
||||
<system:String x:Key="plugin_init_time">Vreme inicijalizacije: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Vreme upita: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Vreme inicijalizacije:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Vreme upita:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Tema</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -42,8 +42,8 @@
|
|||
<system:String x:Key="actionKeywords">Anahtar Kelimeler</system:String>
|
||||
<system:String x:Key="pluginDirectory">Eklenti Klasörü</system:String>
|
||||
<system:String x:Key="author">Yapımcı</system:String>
|
||||
<system:String x:Key="plugin_init_time">Açılış Süresi: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Sorgu Süresi: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Açılış Süresi:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Sorgu Süresi:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Temalar</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--MainWindow-->
|
||||
|
|
@ -36,8 +36,8 @@
|
|||
<system:String x:Key="actionKeywords">Ключове слово</system:String>
|
||||
<system:String x:Key="pluginDirectory">Директорія плагіну</system:String>
|
||||
<system:String x:Key="author">Автор</system:String>
|
||||
<system:String x:Key="plugin_init_time">Ініціалізація: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">Запит: {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">Ініціалізація:</system:String>
|
||||
<system:String x:Key="plugin_query_time">Запит:</system:String>
|
||||
|
||||
<!--Setting Theme-->
|
||||
<system:String x:Key="theme">Теми</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--主窗体-->
|
||||
|
|
@ -41,8 +41,8 @@
|
|||
<system:String x:Key="actionKeywords">触发关键字</system:String>
|
||||
<system:String x:Key="pluginDirectory">插件目录</system:String>
|
||||
<system:String x:Key="author">作者</system:String>
|
||||
<system:String x:Key="plugin_init_time">加载耗时 {0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">查询耗时 {0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">加载耗时</system:String>
|
||||
<system:String x:Key="plugin_query_time">查询耗时</system:String>
|
||||
|
||||
<!--设置,主题-->
|
||||
<system:String x:Key="theme">主题</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<!--主視窗-->
|
||||
|
|
@ -36,8 +36,8 @@
|
|||
<system:String x:Key="actionKeywords">觸發關鍵字</system:String>
|
||||
<system:String x:Key="pluginDirectory">外掛資料夾</system:String>
|
||||
<system:String x:Key="author">作者</system:String>
|
||||
<system:String x:Key="plugin_init_time">載入耗時:{0}ms</system:String>
|
||||
<system:String x:Key="plugin_query_time">查詢耗時:{0}ms</system:String>
|
||||
<system:String x:Key="plugin_init_time">載入耗時:</system:String>
|
||||
<system:String x:Key="plugin_query_time">查詢耗時:</system:String>
|
||||
|
||||
<!--設定,主題-->
|
||||
<system:String x:Key="theme">主題</system:String>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 114 KiB |
|
|
@ -62,7 +62,7 @@
|
|||
</TextBlock>
|
||||
</StackPanel>
|
||||
<TextBlock Style="{DynamicResource ItemTitleStyle}" DockPanel.Dock="Left"
|
||||
VerticalAlignment="Center" ToolTip="{Binding Result.Title}" x:Name="Title"
|
||||
VerticalAlignment="Center" ToolTip="{Binding ShowTitleToolTip}" x:Name="Title"
|
||||
Text="{Binding Result.Title}">
|
||||
<vm:ResultsViewModel.FormattedText>
|
||||
<MultiBinding Converter="{StaticResource HighlightTextConverter}">
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
</MultiBinding>
|
||||
</vm:ResultsViewModel.FormattedText>
|
||||
</TextBlock>
|
||||
<TextBlock Style="{DynamicResource ItemSubTitleStyle}" ToolTip="{Binding Result.SubTitle}"
|
||||
<TextBlock Style="{DynamicResource ItemSubTitleStyle}" ToolTip="{Binding ShowSubTitleToolTip}"
|
||||
Grid.Row="1" x:Name="SubTitle" Text="{Binding Result.SubTitle}" MinWidth="750">
|
||||
<vm:ResultsViewModel.FormattedText>
|
||||
<MultiBinding Converter="{StaticResource HighlightTextConverter}">
|
||||
|
|
|
|||
|
|
@ -175,14 +175,16 @@
|
|||
|
||||
<TextBlock Text="{DynamicResource actionKeywords}"
|
||||
Visibility="{Binding ActionKeywordsVisibility}"
|
||||
Margin="20 0 0 0" MaxWidth="100"/>
|
||||
Margin="20 0 0 0"/>
|
||||
<TextBlock Text="{Binding ActionKeywordsText}"
|
||||
Visibility="{Binding ActionKeywordsVisibility}"
|
||||
ToolTip="Change Action Keywords"
|
||||
Margin="5 0 0 0" Cursor="Hand" Foreground="Blue"
|
||||
MouseUp="OnPluginActionKeywordsClick" MaxWidth="100" />
|
||||
<TextBlock Text="{Binding InitilizaTime}" Margin="10 0 0 0" MaxWidth="100"/>
|
||||
<TextBlock Text="{Binding QueryTime}" Margin="10 0 0 0" MaxWidth="100"/>
|
||||
<TextBlock Text="{DynamicResource plugin_init_time}" Margin="10 0 0 0" MaxWidth="100"/>
|
||||
<TextBlock Text="{Binding InitilizaTime}" Margin="5 0 0 0" MaxWidth="100"/>
|
||||
<TextBlock Text="{DynamicResource plugin_query_time}" Margin="10 0 0 0" MaxWidth="100"/>
|
||||
<TextBlock Text="{Binding QueryTime}" Margin="5 0 0 0" MaxWidth="100"/>
|
||||
<TextBlock Text="{DynamicResource pluginDirectory}"
|
||||
MaxWidth="100" Cursor="Hand" Margin="40 0 0 0"
|
||||
MouseUp="OnPluginDirecotyClick" Foreground="Blue" />
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
|
@ -21,17 +20,17 @@ namespace Flow.Launcher
|
|||
{
|
||||
private const string StartupPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
|
||||
|
||||
public readonly IPublicAPI _api;
|
||||
private Settings _settings;
|
||||
private SettingWindowViewModel _viewModel;
|
||||
public readonly IPublicAPI API;
|
||||
private Settings settings;
|
||||
private SettingWindowViewModel viewModel;
|
||||
|
||||
public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
_settings = viewModel.Settings;
|
||||
settings = viewModel.Settings;
|
||||
DataContext = viewModel;
|
||||
_viewModel = viewModel;
|
||||
_api = api;
|
||||
this.viewModel = viewModel;
|
||||
API = api;
|
||||
}
|
||||
|
||||
#region General
|
||||
|
|
@ -94,7 +93,7 @@ namespace Flow.Launcher
|
|||
var pythonPath = Path.Combine(pythonDirectory, PluginsLoader.PythonExecutable);
|
||||
if (File.Exists(pythonPath))
|
||||
{
|
||||
_settings.PluginSettings.PythonDirectory = pythonDirectory;
|
||||
settings.PluginSettings.PythonDirectory = pythonDirectory;
|
||||
MessageBox.Show("Remember to restart Flow Launcher use new Python path");
|
||||
}
|
||||
else
|
||||
|
|
@ -111,7 +110,7 @@ namespace Flow.Launcher
|
|||
|
||||
private void OnHotkeyControlLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
HotkeyControl.SetHotkey(_viewModel.Settings.Hotkey, false);
|
||||
HotkeyControl.SetHotkey(viewModel.Settings.Hotkey, false);
|
||||
}
|
||||
|
||||
void OnHotkeyChanged(object sender, EventArgs e)
|
||||
|
|
@ -129,8 +128,8 @@ namespace Flow.Launcher
|
|||
Application.Current.MainWindow.Visibility = Visibility.Hidden;
|
||||
}
|
||||
});
|
||||
RemoveHotkey(_settings.Hotkey);
|
||||
_settings.Hotkey = HotkeyControl.CurrentHotkey.ToString();
|
||||
RemoveHotkey(settings.Hotkey);
|
||||
settings.Hotkey = HotkeyControl.CurrentHotkey.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +158,7 @@ namespace Flow.Launcher
|
|||
|
||||
private void OnDeleteCustomHotkeyClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var item = _viewModel.SelectedCustomPluginHotkey;
|
||||
var item = viewModel.SelectedCustomPluginHotkey;
|
||||
if (item == null)
|
||||
{
|
||||
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
|
||||
|
|
@ -173,17 +172,17 @@ namespace Flow.Launcher
|
|||
MessageBox.Show(deleteWarning, InternationalizationManager.Instance.GetTranslation("delete"),
|
||||
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
|
||||
{
|
||||
_settings.CustomPluginHotkeys.Remove(item);
|
||||
settings.CustomPluginHotkeys.Remove(item);
|
||||
RemoveHotkey(item.Hotkey);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnnEditCustomHotkeyClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var item = _viewModel.SelectedCustomPluginHotkey;
|
||||
var item = viewModel.SelectedCustomPluginHotkey;
|
||||
if (item != null)
|
||||
{
|
||||
CustomQueryHotkeySetting window = new CustomQueryHotkeySetting(this, _settings);
|
||||
CustomQueryHotkeySetting window = new CustomQueryHotkeySetting(this, settings);
|
||||
window.UpdateItem(item);
|
||||
window.ShowDialog();
|
||||
}
|
||||
|
|
@ -195,7 +194,7 @@ namespace Flow.Launcher
|
|||
|
||||
private void OnAddCustomeHotkeyClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
new CustomQueryHotkeySetting(this, _settings).ShowDialog();
|
||||
new CustomQueryHotkeySetting(this, settings).ShowDialog();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -204,17 +203,17 @@ namespace Flow.Launcher
|
|||
|
||||
private void OnPluginToggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var id = _viewModel.SelectedPlugin.PluginPair.Metadata.ID;
|
||||
var id = viewModel.SelectedPlugin.PluginPair.Metadata.ID;
|
||||
// used to sync the current status from the plugin manager into the setting to keep consistency after save
|
||||
_settings.PluginSettings.Plugins[id].Disabled = _viewModel.SelectedPlugin.PluginPair.Metadata.Disabled;
|
||||
settings.PluginSettings.Plugins[id].Disabled = viewModel.SelectedPlugin.PluginPair.Metadata.Disabled;
|
||||
}
|
||||
|
||||
private void OnPluginActionKeywordsClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
var id = _viewModel.SelectedPlugin.PluginPair.Metadata.ID;
|
||||
ActionKeywords changeKeywordsWindow = new ActionKeywords(id, _settings);
|
||||
var id = viewModel.SelectedPlugin.PluginPair.Metadata.ID;
|
||||
ActionKeywords changeKeywordsWindow = new ActionKeywords(id, settings, viewModel.SelectedPlugin);
|
||||
changeKeywordsWindow.ShowDialog();
|
||||
}
|
||||
}
|
||||
|
|
@ -223,7 +222,7 @@ namespace Flow.Launcher
|
|||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
var website = _viewModel.SelectedPlugin.PluginPair.Metadata.Website;
|
||||
var website = viewModel.SelectedPlugin.PluginPair.Metadata.Website;
|
||||
if (!string.IsNullOrEmpty(website))
|
||||
{
|
||||
var uri = new Uri(website);
|
||||
|
|
@ -239,7 +238,7 @@ namespace Flow.Launcher
|
|||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
var directory = _viewModel.SelectedPlugin.PluginPair.Metadata.PluginDirectory;
|
||||
var directory = viewModel.SelectedPlugin.PluginPair.Metadata.PluginDirectory;
|
||||
if (!string.IsNullOrEmpty(directory))
|
||||
FilesFolders.OpenPath(directory);
|
||||
}
|
||||
|
|
@ -250,7 +249,7 @@ namespace Flow.Launcher
|
|||
|
||||
private void OnTestProxyClick(object sender, RoutedEventArgs e)
|
||||
{ // TODO: change to command
|
||||
var msg = _viewModel.TestProxy();
|
||||
var msg = viewModel.TestProxy();
|
||||
MessageBox.Show(msg); // TODO: add message box service
|
||||
}
|
||||
|
||||
|
|
@ -258,7 +257,7 @@ namespace Flow.Launcher
|
|||
|
||||
private async void OnCheckUpdates(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_viewModel.UpdateApp(); // TODO: change to command
|
||||
viewModel.UpdateApp(); // TODO: change to command
|
||||
}
|
||||
|
||||
private void OnRequestNavigate(object sender, RequestNavigateEventArgs e)
|
||||
|
|
@ -269,7 +268,7 @@ namespace Flow.Launcher
|
|||
|
||||
private void OnClosed(object sender, EventArgs e)
|
||||
{
|
||||
_viewModel.Save();
|
||||
viewModel.Save();
|
||||
}
|
||||
|
||||
private void OnCloseExecuted(object sender, ExecutedRoutedEventArgs e)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
using System.Windows;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Flow.Launcher.Plugin;
|
||||
using Flow.Launcher.Core.Resource;
|
||||
using Flow.Launcher.Infrastructure.Image;
|
||||
using Flow.Launcher.Core.Plugin;
|
||||
|
||||
namespace Flow.Launcher.ViewModel
|
||||
{
|
||||
|
|
@ -22,8 +23,17 @@ namespace Flow.Launcher.ViewModel
|
|||
}
|
||||
}
|
||||
public Visibility ActionKeywordsVisibility => PluginPair.Metadata.ActionKeywords.Count > 1 ? Visibility.Collapsed : Visibility.Visible;
|
||||
public string InitilizaTime => string.Format(_translator.GetTranslation("plugin_init_time"), PluginPair.Metadata.InitTime);
|
||||
public string QueryTime => string.Format(_translator.GetTranslation("plugin_query_time"), PluginPair.Metadata.AvgQueryTime);
|
||||
public string InitilizaTime => PluginPair.Metadata.InitTime.ToString() + "ms";
|
||||
public string QueryTime => PluginPair.Metadata.AvgQueryTime + "ms";
|
||||
public string ActionKeywordsText => string.Join(Query.ActionKeywordSeperater, PluginPair.Metadata.ActionKeywords);
|
||||
|
||||
public void ChangeActionKeyword(string newActionKeyword, string oldActionKeyword)
|
||||
{
|
||||
PluginManager.ReplaceActionKeyword(PluginPair.Metadata.ID, oldActionKeyword, newActionKeyword);
|
||||
|
||||
OnPropertyChanged(nameof(ActionKeywordsText));
|
||||
}
|
||||
|
||||
public bool IsActionKeywordRegistered(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,14 @@ namespace Flow.Launcher.ViewModel
|
|||
|
||||
public string OpenResultModifiers => Settings.OpenResultModifiers;
|
||||
|
||||
public string ShowTitleToolTip => string.IsNullOrEmpty(Result.TitleToolTip)
|
||||
? Result.Title
|
||||
: Result.TitleToolTip;
|
||||
|
||||
public string ShowSubTitleToolTip => string.IsNullOrEmpty(Result.SubTitleToolTip)
|
||||
? Result.SubTitle
|
||||
: Result.SubTitleToolTip;
|
||||
|
||||
public ImageSource Image
|
||||
{
|
||||
get
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.6 KiB |
|
|
@ -174,7 +174,7 @@ namespace Flow.Launcher.Plugin.Explorer
|
|||
{
|
||||
try
|
||||
{
|
||||
Process.Start("explorer.exe", $" /select,\"{record.FullPath}\"");
|
||||
FilesFolders.OpenContainingFolder(record.FullPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
internal const string DifferentUserIconImagePath = "Images\\user.png";
|
||||
internal const string IndexingOptionsIconImagePath = "Images\\windowsindexingoptions.png";
|
||||
|
||||
internal const string DefaultFolderSubtitleString = "Ctrl + Enter to open the directory";
|
||||
internal const string ToolTipOpenDirectory = "Ctrl + Enter to open the directory";
|
||||
|
||||
internal const string ToolTipOpenContainingFolder = "Ctrl + Enter to open the containing folder";
|
||||
|
||||
internal const char AllFilesFolderSearchWildcard = '>';
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
|
|||
|
||||
if (fileSystemInfo is System.IO.DirectoryInfo)
|
||||
{
|
||||
folderList.Add(resultManager.CreateFolderResult(fileSystemInfo.Name, Constants.DefaultFolderSubtitleString, fileSystemInfo.FullName, query, true, false));
|
||||
folderList.Add(resultManager.CreateFolderResult(fileSystemInfo.Name, fileSystemInfo.FullName, fileSystemInfo.FullName, query, true, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
|
@ -18,12 +18,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
|
||||
internal static Dictionary<string, string> LoadEnvironmentStringPaths()
|
||||
{
|
||||
var envStringPaths = new Dictionary<string, string>();
|
||||
var envStringPaths = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
foreach (DictionaryEntry special in Environment.GetEnvironmentVariables())
|
||||
{
|
||||
if (Directory.Exists(special.Value.ToString()))
|
||||
{
|
||||
// Variables are returned with a mixture of all upper/lower case.
|
||||
// Call ToLower() to make the results look consistent
|
||||
envStringPaths.Add(special.Key.ToString().ToLower(), special.Value.ToString());
|
||||
}
|
||||
}
|
||||
|
|
@ -82,11 +84,12 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
|
||||
foreach (var p in environmentVariables)
|
||||
{
|
||||
if (p.Key.StartsWith(search))
|
||||
if (p.Key.StartsWith(search, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
results.Add(new ResultManager(context).CreateFolderResult($"%{p.Key}%", p.Value, p.Value, query));
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.FolderLinks
|
|||
return folderLinks
|
||||
.Select(item =>
|
||||
new ResultManager(context)
|
||||
.CreateFolderResult(item.Nickname, Constants.DefaultFolderSubtitleString, item.Path, query))
|
||||
.CreateFolderResult(item.Nickname, item.Path, item.Path, query))
|
||||
.ToList();
|
||||
|
||||
string search = query.Search.ToLower();
|
||||
|
|
@ -21,7 +21,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.FolderLinks
|
|||
|
||||
return queriedFolderLinks.Select(item =>
|
||||
new ResultManager(context)
|
||||
.CreateFolderResult(item.Nickname, Constants.DefaultFolderSubtitleString, item.Path, query))
|
||||
.CreateFolderResult(item.Nickname, item.Path, item.Path, query))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Flow.Launcher.Infrastructure;
|
||||
using Flow.Launcher.Plugin.SharedCommands;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
|
|
@ -38,13 +39,15 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string changeTo = path.EndsWith(Constants.DirectorySeperator) ? path : path + Constants.DirectorySeperator;
|
||||
context.API.ChangeQuery(string.IsNullOrEmpty(query.ActionKeyword) ?
|
||||
changeTo :
|
||||
query.ActionKeyword + " " + changeTo);
|
||||
return false;
|
||||
},
|
||||
TitleToolTip = Constants.ToolTipOpenDirectory,
|
||||
SubTitleToolTip = Constants.ToolTipOpenDirectory,
|
||||
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path, ShowIndexState = showIndexState, WindowsIndexed = windowsIndexed }
|
||||
};
|
||||
}
|
||||
|
|
@ -85,6 +88,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
FilesFolders.OpenPath(retrievedDirectoryPath);
|
||||
return true;
|
||||
},
|
||||
TitleToolTip = retrievedDirectoryPath,
|
||||
SubTitleToolTip = retrievedDirectoryPath,
|
||||
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = retrievedDirectoryPath, ShowIndexState = true, WindowsIndexed = windowsIndexed }
|
||||
};
|
||||
}
|
||||
|
|
@ -101,7 +106,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
{
|
||||
try
|
||||
{
|
||||
FilesFolders.OpenPath(filePath);
|
||||
if (c.SpecialKeyState.CtrlPressed)
|
||||
{
|
||||
FilesFolders.OpenContainingFolder(filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
FilesFolders.OpenPath(filePath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -110,6 +122,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
|
||||
return true;
|
||||
},
|
||||
TitleToolTip = Constants.ToolTipOpenContainingFolder,
|
||||
SubTitleToolTip = Constants.ToolTipOpenContainingFolder,
|
||||
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath, ShowIndexState = showIndexState, WindowsIndexed = windowsIndexed }
|
||||
};
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
|
|||
if (dataReaderResults.GetString(2) == "Directory")
|
||||
{
|
||||
folderResults.Add(resultManager.CreateFolderResult(
|
||||
dataReaderResults.GetString(0),
|
||||
Constants.DefaultFolderSubtitleString,
|
||||
dataReaderResults.GetString(0),
|
||||
dataReaderResults.GetString(1),
|
||||
dataReaderResults.GetString(1),
|
||||
query, true, true));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
|
@ -17,7 +17,6 @@ namespace Flow.Launcher.Plugin.PluginManagement
|
|||
public class Main : IPlugin, IPluginI18n
|
||||
{
|
||||
private static string APIBASE = "http://api.wox.one";
|
||||
private static string PluginConfigName = "plugin.json";
|
||||
private static string pluginSearchUrl = APIBASE + "/plugin/search/";
|
||||
private const string ListCommand = "list";
|
||||
private const string InstallCommand = "install";
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.6 KiB |
|
|
@ -1,55 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<ProjectGuid>{03FFA443-5F50-48D5-8869-F3DF316803AA}</ProjectGuid>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>HelloWorldCSharp</RootNamespace>
|
||||
<AssemblyName>HelloWorldCSharp</AssemblyName>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<ApplicationIcon />
|
||||
<OutputType>Library</OutputType>
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\Output\Debug\Plugins\HelloWorldCSharp\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\Output\Release\Plugins\HelloWorldCSharp\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="plugin.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Images\app.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
Before Width: | Height: | Size: 5.3 KiB |
|
|
@ -1,28 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Flow.Launcher.Plugin;
|
||||
|
||||
namespace HelloWorldCSharp
|
||||
{
|
||||
class Main : IPlugin
|
||||
{
|
||||
public List<Result> Query(Query query)
|
||||
{
|
||||
var result = new Result
|
||||
{
|
||||
Title = "Hello World from CSharp",
|
||||
SubTitle = $"Query: {query.Search}",
|
||||
IcoPath = "app.png"
|
||||
};
|
||||
return new List<Result> {result};
|
||||
}
|
||||
|
||||
public void Init(PluginInitContext context)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"ID": "CEA0FDFC6D3B4085823D60DC76F28844",
|
||||
"ActionKeyword": "hc",
|
||||
"Name": "Hello World CSharp",
|
||||
"Description": "Hello World CSharp",
|
||||
"Author": "happlebao",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
|
||||
"ExecuteFileName": "HelloWorldCSharp.dll",
|
||||
"IcoPath": "app.png",
|
||||
"Disabled": true
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<OutputPath>..\..\Output\Debug\Plugins\HelloWorldFSharp\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<OutputPath>..\..\Output\Release\Plugins\HelloWorldFSharp\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Images\app.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="plugin.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Compile Include="Main.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="FSharp.Core" Version="4.7.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
Before Width: | Height: | Size: 5.3 KiB |
|
|
@ -1,31 +0,0 @@
|
|||
namespace HelloWorldFSharp
|
||||
|
||||
open Flow.Launcher.Plugin
|
||||
open System.Collections.Generic
|
||||
|
||||
type HelloWorldFSharpPlugin() =
|
||||
|
||||
let mutable initContext = PluginInitContext()
|
||||
|
||||
interface IPlugin with
|
||||
member this.Init (context: PluginInitContext) =
|
||||
initContext <- context
|
||||
|
||||
member this.Query (query: Query) =
|
||||
List<Result> [
|
||||
Result (Title = "Hello World from F#",
|
||||
SubTitle = sprintf "Query: %s" query.Search)
|
||||
|
||||
Result (Title = "Browse source code of this plugin",
|
||||
SubTitle = "click to open in browser",
|
||||
Action = (fun ctx ->
|
||||
initContext.CurrentPluginMetadata.Website
|
||||
|> System.Diagnostics.Process.Start
|
||||
|> ignore
|
||||
true))
|
||||
|
||||
Result (Title = "Trigger a tray message",
|
||||
Action = (fun _ ->
|
||||
initContext.API.ShowMsg ("Sample tray message", "from the F# plugin")
|
||||
false))
|
||||
]
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"ID": "8FF5D5C1F8194958A12E8668FB7ECC04",
|
||||
"ActionKeyword": "hf",
|
||||
"Name": "Hello World FSharp",
|
||||
"Description": "Hello World FSharp",
|
||||
"Author": "Ioannis G.",
|
||||
"Version": "1.0.0",
|
||||
"Language": "fsharp",
|
||||
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
|
||||
"ExecuteFileName": "HelloWorldFSharp.dll",
|
||||
"IcoPath": "Images\\app.png"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 5.3 KiB |
|
|
@ -1,27 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from flow.launcher import Flow.Launcher
|
||||
|
||||
class HelloWorld(FlowLauncher):
|
||||
|
||||
def query(self, query):
|
||||
results = []
|
||||
results.append({
|
||||
"Title": "Hello World",
|
||||
"SubTitle": "Query: {}".format(query),
|
||||
"IcoPath":"Images/app.ico",
|
||||
"ContextData": "ctxData"
|
||||
})
|
||||
return results
|
||||
|
||||
def context_menu(self, data):
|
||||
results = []
|
||||
results.append({
|
||||
"Title": "Context menu entry",
|
||||
"SubTitle": "Data: {}".format(data),
|
||||
"IcoPath":"Images/app.ico"
|
||||
})
|
||||
return results
|
||||
|
||||
if __name__ == "__main__":
|
||||
HelloWorld()
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"ID":"2f4e384e-76ce-45c3-aea2-b16f5e5c328f",
|
||||
"ActionKeyword":"h",
|
||||
"Name":"Hello World Python",
|
||||
"Description":"Hello World",
|
||||
"Author":"happlebao",
|
||||
"Version":"1.0",
|
||||
"Language":"python",
|
||||
"Website":"https://github.com/Flow-Launcher/Flow.Launcher",
|
||||
"IcoPath":"Images\\app.png",
|
||||
"ExecuteFileName":"main.py"
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
Flow Launcher
|
||||
=============
|
||||
<p align="center">
|
||||
<img width="500px" src="https://github.com/Flow-Launcher/Flow.Launcher/blob/5ba4514f31e624c679628d4dfe89036c0e24006c/Doc/Logo/resources/flow-header-square-transparent.png">
|
||||
</p>
|
||||
|
||||

|
||||
[](https://ci.appveyor.com/project/JohnTheGr8/flow-launcher/branch/dev)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ function Copy-Resources ($path, $config) {
|
|||
$output = "$path\Output"
|
||||
$target = "$output\$config"
|
||||
Copy-Item -Recurse -Force $project\Images\* $target\Images\
|
||||
Copy-Item -Recurse -Force $path\Plugins\HelloWorldPython $target\Plugins\HelloWorldPython
|
||||
Copy-Item -Recurse -Force $path\JsonRPC $target\JsonRPC
|
||||
# making version static as multiple versions can exist in the nuget folder and in the case a breaking change is introduced.
|
||||
Copy-Item -Force $env:USERPROFILE\.nuget\packages\squirrel.windows\1.5.2\tools\Squirrel.exe $output\Update.exe
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version: '0.9.0.{build}'
|
||||
version: '1.0.0.{build}'
|
||||
|
||||
init:
|
||||
- ps: |
|
||||
|
|
|
|||