Merge pull request #2769 from Flow-Launcher/localize-missing-python-js-dialog

Localize startup messages about missing Python/NodeJS
This commit is contained in:
Jeremy Wu 2024-07-22 22:43:24 +10:00 committed by GitHub
commit 39f6cd6b7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 60 additions and 31 deletions

View file

@ -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");

View file

@ -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
}
/// <summary>
/// Save json and ISavable
/// Save json and ISavable
/// </summary>
public static void Save()
{
@ -202,12 +203,21 @@ namespace Flow.Launcher.Core.Plugin
}
}
InternationalizationManager.Instance.AddPluginLanguageDirectories(GetPluginsForInterface<IPluginI18n>());
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<PluginPair>();
if (!NonGlobalPlugins.ContainsKey(query.ActionKeyword))
return GlobalPlugins;
var plugin = NonGlobalPlugins[query.ActionKeyword];
return new List<PluginPair>
{
@ -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);

View file

@ -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<PluginPair> plugins)
{
foreach (var plugin in PluginManager.GetPluginsForInterface<IPluginI18n>())
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)

View file

@ -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

View file

@ -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">
<!-- Startup -->
<system:String x:Key="runtimePluginInstalledChooseRuntimePrompt">
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
</system:String>
<system:String x:Key="runtimePluginChooseRuntimeExecutable">Please select the {0} executable</system:String>
<system:String x:Key="runtimePluginUnableToSetExecutablePath">Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).</system:String>
<system:String x:Key="failedToInitializePluginsTitle">Fail to Init Plugins</system:String>
<system:String x:Key="failedToInitializePluginsMessage">Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help</system:String>
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Failed to register hotkey "{0}". The hotkey may be in use by another program. Change to a different hotkey, or exit another program.</system:String>
<system:String x:Key="MessageBoxTitle">Flow Launcher</system:String>

View file

@ -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">
<!-- Startup -->
<system:String x:Key="runtimePluginInstalledChooseRuntimePrompt">
Flow определил, что вы установили {0} плагины, которым требуется {1} для работы. Скачать {1}?
{2}{2}
Кликните нет, если он уже установлен, и вам будет предложено выбрать папку, где находится исполняемый файл {1}
</system:String>
<system:String x:Key="runtimePluginChooseRuntimeExecutable">Пожалуйста, выберите исполняемый файл {0}</system:String>
<system:String x:Key="runtimePluginUnableToSetExecutablePath">Не удалось установить путь к исполняемому файлу {0}, пожалуйста, попробуйте через настройки Flow (прокрутите вниз).</system:String>
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Не удалось зарегистрировать сочетание клавиш &quot;{0}&quot;. Возможно, оно используется другой программой. Измените сочетание клавиш или закройте другую программу.</system:String>
<system:String x:Key="MessageBoxTitle">Flow Launcher</system:String>