From dd1ce002983529a37e6aece7cb3f9973628bb94c Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Tue, 17 Sep 2024 22:16:44 +0200 Subject: [PATCH] WIP --- src/common/ManagedCommon/LanguageHelper.cs | 50 +++++++++++++++++++ .../AdvancedPasteXAML/App.xaml.cs | 6 +++ .../EnvironmentVariablesXAML/App.xaml.cs | 6 +++ .../FileLocksmithXAML/App.xaml.cs | 6 +++ .../Workspaces/WorkspacesEditor/App.xaml.cs | 15 ++++++ .../WorkspacesLauncherUI/App.xaml.cs | 17 ++++++- .../colorPicker/ColorPickerUI/App.xaml.cs | 15 ++++++ .../editor/FancyZonesEditor/App.xaml.cs | 15 ++++++ .../RegistryPreviewXAML/App.xaml.cs | 8 +++ src/runner/settings_window.cpp | 6 +++ 10 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 src/common/ManagedCommon/LanguageHelper.cs diff --git a/src/common/ManagedCommon/LanguageHelper.cs b/src/common/ManagedCommon/LanguageHelper.cs new file mode 100644 index 00000000000..90791a03bc5 --- /dev/null +++ b/src/common/ManagedCommon/LanguageHelper.cs @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.IO.Abstractions; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace ManagedCommon +{ + public static class LanguageHelper + { + public const string SettingsFilePath = "\\Microsoft\\PowerToys\\"; + public const string SettingsFile = "language.json"; + + internal sealed class OutGoingLanguageSettings + { + [JsonPropertyName("language")] + public string LanguageTag { get; set; } + } + + public static string LoadLanguage() + { + FileSystem fileSystem = new FileSystem(); + var localAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + var file = localAppDataDir + SettingsFilePath + SettingsFile; + + if (fileSystem.File.Exists(file)) + { + try + { + Stream inputStream = fileSystem.File.Open(file, FileMode.Open); + StreamReader reader = new StreamReader(inputStream); + string data = reader.ReadToEnd(); + inputStream.Close(); + reader.Dispose(); + + return JsonSerializer.Deserialize(data).LanguageTag; + } + catch (Exception) + { + } + } + + return string.Empty; + } + } +} diff --git a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs index 3e3fc9c4b50..3f990ef6faf 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs +++ b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs @@ -50,6 +50,12 @@ public partial class App : Application, IDisposable /// public App() { + string appLanguage = LanguageHelper.LoadLanguage(); + if (!string.IsNullOrEmpty(appLanguage)) + { + Microsoft.Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = appLanguage; + } + this.InitializeComponent(); Host = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder().UseContentRoot(AppContext.BaseDirectory).ConfigureServices((context, services) => diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs index 61c8e33f178..bc6f5aa1dac 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs @@ -44,6 +44,12 @@ public static T GetService() /// public App() { + string appLanguage = LanguageHelper.LoadLanguage(); + if (!string.IsNullOrEmpty(appLanguage)) + { + Microsoft.Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = appLanguage; + } + this.InitializeComponent(); Host = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder().UseContentRoot(AppContext.BaseDirectory).ConfigureServices((context, services) => diff --git a/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithXAML/App.xaml.cs b/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithXAML/App.xaml.cs index 8e5ff669de5..e6186c46c8f 100644 --- a/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithXAML/App.xaml.cs +++ b/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithXAML/App.xaml.cs @@ -23,6 +23,12 @@ public partial class App : Application /// public App() { + string appLanguage = LanguageHelper.LoadLanguage(); + if (!string.IsNullOrEmpty(appLanguage)) + { + Microsoft.Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = appLanguage; + } + Logger.InitializeLogger("\\File Locksmith\\FileLocksmithUI\\Logs"); this.InitializeComponent(); diff --git a/src/modules/Workspaces/WorkspacesEditor/App.xaml.cs b/src/modules/Workspaces/WorkspacesEditor/App.xaml.cs index 2edfd5c4b8f..20dfed7712c 100644 --- a/src/modules/Workspaces/WorkspacesEditor/App.xaml.cs +++ b/src/modules/Workspaces/WorkspacesEditor/App.xaml.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Globalization; using System.Threading; using System.Windows; @@ -40,6 +41,20 @@ private void OnStartup(object sender, StartupEventArgs e) Logger.InitializeLogger("\\Workspaces\\Logs"); AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; + var languageTag = LanguageHelper.LoadLanguage(); + + if (!string.IsNullOrEmpty(languageTag)) + { + try + { + WorkspacesEditor.Properties.Resources.Culture = new System.Globalization.CultureInfo(languageTag); + } + catch (CultureNotFoundException ex) + { + Logger.LogError("CultureNotFoundException: " + ex.Message); + } + } + const string appName = "Local\\PowerToys_Workspaces_Editor_InstanceMutex"; bool createdNew; _instanceMutex = new Mutex(true, appName, out createdNew); diff --git a/src/modules/Workspaces/WorkspacesLauncherUI/App.xaml.cs b/src/modules/Workspaces/WorkspacesLauncherUI/App.xaml.cs index 0709a59c09f..4b9f0f66345 100644 --- a/src/modules/Workspaces/WorkspacesLauncherUI/App.xaml.cs +++ b/src/modules/Workspaces/WorkspacesLauncherUI/App.xaml.cs @@ -3,13 +3,12 @@ // See the LICENSE file in the project root for more information. using System; +using System.Globalization; using System.Threading; using System.Windows; -using System.Windows.Forms.Design.Behavior; using Common.UI; using ManagedCommon; -using WorkspacesLauncherUI.Utils; using WorkspacesLauncherUI.ViewModels; namespace WorkspacesLauncherUI @@ -38,6 +37,20 @@ private void OnStartup(object sender, StartupEventArgs e) Logger.InitializeLogger("\\Workspaces\\Logs"); AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; + var languageTag = LanguageHelper.LoadLanguage(); + + if (!string.IsNullOrEmpty(languageTag)) + { + try + { + WorkspacesLauncherUI.Properties.Resources.Culture = new System.Globalization.CultureInfo(languageTag); + } + catch (CultureNotFoundException ex) + { + Logger.LogError("CultureNotFoundException: " + ex.Message); + } + } + const string appName = "Local\\PowerToys_Workspaces_Launcher_InstanceMutex"; bool createdNew; _instanceMutex = new Mutex(true, appName, out createdNew); diff --git a/src/modules/colorPicker/ColorPickerUI/App.xaml.cs b/src/modules/colorPicker/ColorPickerUI/App.xaml.cs index b90e2318924..95c4aa648cb 100644 --- a/src/modules/colorPicker/ColorPickerUI/App.xaml.cs +++ b/src/modules/colorPicker/ColorPickerUI/App.xaml.cs @@ -4,11 +4,13 @@ using System; using System.ComponentModel.Composition; +using System.Globalization; using System.Threading; using System.Windows; using ColorPicker.Mouse; using ManagedCommon; +using Microsoft.PowerToys.Settings.UI.Library; namespace ColorPickerUI { @@ -29,6 +31,19 @@ public partial class App : Application, IDisposable protected override void OnStartup(StartupEventArgs e) { + try + { + string appLanguage = LanguageModel.LoadSetting(); + if (!string.IsNullOrEmpty(appLanguage)) + { + ColorPicker.Properties.Resources.Culture = new System.Globalization.CultureInfo(appLanguage); + } + } + catch (CultureNotFoundException) + { + // Add logging here + } + NativeThreadCTS = new CancellationTokenSource(); ExitToken = NativeThreadCTS.Token; diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs index 2edb096018b..2906c759f1b 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; +using System.Globalization; using System.Threading; using System.Windows; using System.Windows.Input; @@ -55,6 +56,20 @@ private void DebugModeCheck() public App() { + var languageTag = LanguageHelper.LoadLanguage(); + + if (!string.IsNullOrEmpty(languageTag)) + { + try + { + FancyZonesEditor.Properties.Resources.Culture = new System.Globalization.CultureInfo(languageTag); + } + catch (CultureNotFoundException ex) + { + Logger.LogError("CultureNotFoundException: " + ex.Message); + } + } + Logger.InitializeLogger("\\FancyZones\\Editor\\Logs"); // DebugModeCheck(); diff --git a/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml.cs b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml.cs index 01007f56100..a6a3898f0f3 100644 --- a/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml.cs +++ b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml.cs @@ -5,6 +5,7 @@ using System; using System.Web; +using ManagedCommon; using Microsoft.UI.Xaml; using Microsoft.Windows.AppLifecycle; using Windows.ApplicationModel.Activation; @@ -25,6 +26,13 @@ public partial class App : Application /// public App() { + string appLanguage = LanguageHelper.LoadLanguage(); + + if (!string.IsNullOrEmpty(appLanguage)) + { + Microsoft.Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = appLanguage; + } + this.InitializeComponent(); } diff --git a/src/runner/settings_window.cpp b/src/runner/settings_window.cpp index 6b48cfaadc8..d6058e62e19 100644 --- a/src/runner/settings_window.cpp +++ b/src/runner/settings_window.cpp @@ -233,6 +233,12 @@ void dispatch_received_json(const std::wstring& json_to_parse) SendMessageW(pt_main_window, WM_CLOSE, 0, 0); } } + else if (name == L"language") + { + constexpr const wchar_t* language_filename = L"\\language.json"; + const std::wstring save_file_location = PTSettingsHelper::get_root_save_folder_location() + language_filename; + json::to_file(save_file_location, j); + } } return; }