diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index 40eb1be3e..30e812c6f 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
+using Flow.Launcher.Core.Resource;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -50,14 +51,15 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
return SetPathForPluginPairs(PluginsSettingsFilePath, Language);
}
- if (MessageBox.Show($"Flow detected you have installed {Language} plugins, which " +
- $"will require {EnvName} to run. Would you like to download {EnvName}? " +
- Environment.NewLine + Environment.NewLine +
- "Click no if it's already installed, " +
- $"and you will be prompted to select the folder that contains the {EnvName} executable",
- string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
+ var noRuntimeMessage = string.Format(
+ InternationalizationManager.Instance.GetTranslation("runtimePluginInstalledChooseRuntimePrompt"),
+ Language,
+ EnvName,
+ Environment.NewLine
+ );
+ if (MessageBox.Show(noRuntimeMessage, string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
{
- var msg = $"Please select the {EnvName} executable";
+ var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
string selectedFile;
selectedFile = GetFileFromDialog(msg, FileDialogFilter);
@@ -80,8 +82,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
}
else
{
- MessageBox.Show(
- $"Unable to set {Language} executable path, please try from Flow's settings (scroll down to the bottom).");
+ MessageBox.Show(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index a827e9e7a..f5fa5e518 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -13,6 +13,7 @@ using Flow.Launcher.Plugin;
using ISavable = Flow.Launcher.Plugin.ISavable;
using Flow.Launcher.Plugin.SharedCommands;
using System.Text.Json;
+using Flow.Launcher.Core.Resource;
namespace Flow.Launcher.Core.Plugin
{
@@ -51,7 +52,7 @@ namespace Flow.Launcher.Core.Plugin
}
///
- /// Save json and ISavable
+ /// Save json and ISavable
///
public static void Save()
{
@@ -202,12 +203,21 @@ namespace Flow.Launcher.Core.Plugin
}
}
+ InternationalizationManager.Instance.AddPluginLanguageDirectories(GetPluginsForInterface());
+ InternationalizationManager.Instance.ChangeLanguage(InternationalizationManager.Instance.Settings.Language);
+
if (failedPlugins.Any())
{
var failed = string.Join(",", failedPlugins.Select(x => x.Metadata.Name));
- API.ShowMsg($"Fail to Init Plugins",
- $"Plugins: {failed} - fail to load and would be disabled, please contact plugin creator for help",
- "", false);
+ API.ShowMsg(
+ InternationalizationManager.Instance.GetTranslation("failedToInitializePluginsTitle"),
+ string.Format(
+ InternationalizationManager.Instance.GetTranslation("failedToInitializePluginsMessage"),
+ failed
+ ),
+ "",
+ false
+ );
}
}
@@ -215,11 +225,11 @@ namespace Flow.Launcher.Core.Plugin
{
if (query is null)
return Array.Empty();
-
+
if (!NonGlobalPlugins.ContainsKey(query.ActionKeyword))
return GlobalPlugins;
-
-
+
+
var plugin = NonGlobalPlugins[query.ActionKeyword];
return new List
{
@@ -279,8 +289,8 @@ namespace Flow.Launcher.Core.Plugin
r.PluginID = metadata.ID;
r.OriginQuery = query;
- // ActionKeywordAssigned is used for constructing MainViewModel's query text auto-complete suggestions
- // Plugins may have multi-actionkeywords eg. WebSearches. In this scenario it needs to be overriden on the plugin level
+ // ActionKeywordAssigned is used for constructing MainViewModel's query text auto-complete suggestions
+ // Plugins may have multi-actionkeywords eg. WebSearches. In this scenario it needs to be overriden on the plugin level
if (metadata.ActionKeywords.Count == 1)
r.ActionKeywordAssigned = query.ActionKeyword;
}
@@ -463,7 +473,7 @@ namespace Flow.Launcher.Core.Plugin
// Unzip plugin files to temp folder
var tempFolderPluginPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
System.IO.Compression.ZipFile.ExtractToDirectory(zipFilePath, tempFolderPluginPath);
-
+
if(!plugin.IsFromLocalInstallPath)
File.Delete(zipFilePath);
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 06eb868b8..192ed2e81 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -25,10 +25,6 @@ namespace Flow.Launcher.Core.Resource
public Internationalization()
{
- AddPluginLanguageDirectories();
- LoadDefaultLanguage();
- // we don't want to load /Languages/en.xaml twice
- // so add flowlauncher language directory after load plugin language files
AddFlowLauncherLanguageDirectory();
}
@@ -40,9 +36,9 @@ namespace Flow.Launcher.Core.Resource
}
- private void AddPluginLanguageDirectories()
+ internal void AddPluginLanguageDirectories(IEnumerable plugins)
{
- foreach (var plugin in PluginManager.GetPluginsForInterface())
+ foreach (var plugin in plugins)
{
var location = Assembly.GetAssembly(plugin.Plugin.GetType()).Location;
var dir = Path.GetDirectoryName(location);
@@ -56,6 +52,8 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Internationalization.AddPluginLanguageDirectories|Can't find plugin path <{location}> for <{plugin.Metadata.Name}>");
}
}
+
+ LoadDefaultLanguage();
}
private void LoadDefaultLanguage()
@@ -140,11 +138,14 @@ namespace Flow.Launcher.Core.Resource
private void LoadLanguage(Language language)
{
+ var flowEnglishFile = Path.Combine(Constant.ProgramDirectory, Folder, DefaultFile);
var dicts = Application.Current.Resources.MergedDictionaries;
var filename = $"{language.LanguageCode}{Extension}";
var files = _languageDirectories
.Select(d => LanguageFile(d, filename))
- .Where(f => !string.IsNullOrEmpty(f))
+ // Exclude Flow's English language file since it's built into the binary, and there's no need to load
+ // it again from the file system.
+ .Where(f => !string.IsNullOrEmpty(f) && f != flowEnglishFile)
.ToArray();
if (files.Length > 0)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 765a1a559..4d1adc6cd 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -71,6 +71,9 @@ namespace Flow.Launcher
StringMatcher.Instance = _stringMatcher;
_stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
+ InternationalizationManager.Instance.Settings = _settings;
+ InternationalizationManager.Instance.ChangeLanguage(_settings.Language);
+
PluginManager.LoadPlugins(_settings.PluginSettings);
_mainVM = new MainViewModel(_settings);
@@ -89,11 +92,6 @@ namespace Flow.Launcher
Current.MainWindow = window;
Current.MainWindow.Title = Constant.FlowLauncher;
- // todo temp fix for instance code logic
- // load plugin before change language, because plugin language also needs be changed
- InternationalizationManager.Instance.Settings = _settings;
- InternationalizationManager.Instance.ChangeLanguage(_settings.Language);
-
HotKeyMapper.Initialize(_mainVM);
// main windows needs initialized before theme change because of blur settings
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index f6a90c95e..ffb03b635 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -2,6 +2,17 @@
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">
+
+
+ Flow detected you have installed {0} plugins, which will require {1} to run. Would you like to download {1}?
+ {2}{2}
+ Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
+
+ Please select the {0} executable
+ Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
+ Fail to Init Plugins
+ Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
+
Failed to register hotkey "{0}". The hotkey may be in use by another program. Change to a different hotkey, or exit another program.
Flow Launcher
diff --git a/Flow.Launcher/Languages/ru.xaml b/Flow.Launcher/Languages/ru.xaml
index 416ca67fa..b94b1f540 100644
--- a/Flow.Launcher/Languages/ru.xaml
+++ b/Flow.Launcher/Languages/ru.xaml
@@ -3,6 +3,14 @@
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">
+
+
+ Flow определил, что вы установили {0} плагины, которым требуется {1} для работы. Скачать {1}?
+ {2}{2}
+ Кликните нет, если он уже установлен, и вам будет предложено выбрать папку, где находится исполняемый файл {1}
+
+ Пожалуйста, выберите исполняемый файл {0}
+ Не удалось установить путь к исполняемому файлу {0}, пожалуйста, попробуйте через настройки Flow (прокрутите вниз).
Не удалось зарегистрировать сочетание клавиш "{0}". Возможно, оно используется другой программой. Измените сочетание клавиш или закройте другую программу.
Flow Launcher