mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 09:46:54 +02:00
[General]Support language selection (#34971)
* Language setting * spellcheck * Set FileLocksmithContextMenu package version in AppManifest.xml * Fix ambigious symbol build error * Fix ambigious symbol build error #2 * Revert unneeded changes * Improve perf * try fix ci build
This commit is contained in:
49
src/settings-ui/Settings.UI.Library/LanguageModel.cs
Normal file
49
src/settings-ui/Settings.UI.Library/LanguageModel.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
// 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;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class LanguageModel
|
||||
{
|
||||
public const string SettingsFilePath = "\\Microsoft\\PowerToys\\";
|
||||
public const string SettingsFile = "language.json";
|
||||
|
||||
public string Tag { get; set; }
|
||||
|
||||
public string ResourceID { get; set; }
|
||||
|
||||
public string Language { get; set; }
|
||||
|
||||
public static string LoadSetting()
|
||||
{
|
||||
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<OutGoingLanguageSettings>(data).LanguageTag;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class OutGoingLanguageSettings
|
||||
{
|
||||
[JsonPropertyName("language")]
|
||||
public string LanguageTag { get; set; }
|
||||
|
||||
public OutGoingLanguageSettings()
|
||||
{
|
||||
}
|
||||
|
||||
public OutGoingLanguageSettings(string language)
|
||||
{
|
||||
LanguageTag = language;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,6 +78,12 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
{
|
||||
Logger.InitializeLogger(@"\Settings\Logs");
|
||||
|
||||
string appLanguage = LanguageHelper.LoadLanguage();
|
||||
if (!string.IsNullOrEmpty(appLanguage))
|
||||
{
|
||||
Microsoft.Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = appLanguage;
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
UnhandledException += App_UnhandledException;
|
||||
|
||||
@@ -229,6 +229,25 @@
|
||||
</controls:SettingsGroup>
|
||||
|
||||
<controls:SettingsGroup x:Uid="Appearance_Behavior" IsEnabled="True">
|
||||
<tkcontrols:SettingsCard x:Uid="LanguageHeader" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<ComboBox
|
||||
x:Name="Languages_ComboBox"
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
DisplayMemberPath="Language"
|
||||
ItemsSource="{Binding Languages, Mode=TwoWay}"
|
||||
SelectedIndex="{Binding LanguagesIndex, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<InfoBar
|
||||
x:Uid="LanguageRestartInfo"
|
||||
IsClosable="False"
|
||||
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.LanguageChanged}"
|
||||
IsTabStop="True"
|
||||
Severity="Informational">
|
||||
<InfoBar.ActionButton>
|
||||
<Button x:Uid="LanguageRestartInfoButton" Click="Click_LanguageRestart" />
|
||||
</InfoBar.ActionButton>
|
||||
</InfoBar>
|
||||
|
||||
<tkcontrols:SettingsCard x:Uid="ColorModeHeader" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<tkcontrols:SettingsCard.Description>
|
||||
<HyperlinkButton x:Uid="Windows_Color_Settings" Click="OpenColorsSettings_Click" />
|
||||
|
||||
@@ -130,5 +130,10 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
string r = await Task.FromResult<string>(ShellGetFolder.GetFolderDialog(hwnd));
|
||||
return r;
|
||||
}
|
||||
|
||||
private void Click_LanguageRestart(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.Restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,10 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:schema id="root"
|
||||
xmlns=""
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
@@ -4380,4 +4383,85 @@ Activate by holding the key for the character you want to add an accent to, then
|
||||
<data name="OpenSettings.Content" xml:space="preserve">
|
||||
<value>Open settings</value>
|
||||
</data>
|
||||
<data name="LanguageHeader.Header" xml:space="preserve">
|
||||
<value>Application language</value>
|
||||
</data>
|
||||
<data name="LanguageHeader.Description" xml:space="preserve">
|
||||
<value>PowerToys will use OS language by default.</value>
|
||||
</data>
|
||||
<data name="LanguageRestartInfo.Title" xml:space="preserve">
|
||||
<value>Restart PowerToys for language change to take effect.</value>
|
||||
</data>
|
||||
<data name="LanguageRestartInfoButton.Content" xml:space="preserve">
|
||||
<value>Restart</value>
|
||||
</data>
|
||||
<data name="Default_Language" xml:space="preserve">
|
||||
<value>Windows default</value>
|
||||
</data>
|
||||
<data name="Arabic_Saudi_Arabia_Language" xml:space="preserve">
|
||||
<value>Arabic (Saudi Arabia)</value>
|
||||
</data>
|
||||
<data name="Czech_Language" xml:space="preserve">
|
||||
<value>Czech</value>
|
||||
</data>
|
||||
<data name="German_Language" xml:space="preserve">
|
||||
<value>German</value>
|
||||
</data>
|
||||
<data name="English_Language" xml:space="preserve">
|
||||
<value>English</value>
|
||||
</data>
|
||||
<data name="Spanish_Language" xml:space="preserve">
|
||||
<value>Spanish</value>
|
||||
</data>
|
||||
<data name="Persian_Farsi_Language" xml:space="preserve">
|
||||
<value>Persian (Farsi)</value>
|
||||
</data>
|
||||
<data name="French_Language" xml:space="preserve">
|
||||
<value>French</value>
|
||||
</data>
|
||||
<data name="Hebrew_Israel_Language" xml:space="preserve">
|
||||
<value>Hebrew (Israel)</value>
|
||||
</data>
|
||||
<data name="Hungarian_Language" xml:space="preserve">
|
||||
<value>Hungarian</value>
|
||||
</data>
|
||||
<data name="Italian_Language" xml:space="preserve">
|
||||
<value>Italian</value>
|
||||
</data>
|
||||
<data name="Japanese_Language" xml:space="preserve">
|
||||
<value>Japanese</value>
|
||||
</data>
|
||||
<data name="Korean_Language" xml:space="preserve">
|
||||
<value>Korean</value>
|
||||
</data>
|
||||
<data name="Dutch_Language" xml:space="preserve">
|
||||
<value>Dutch</value>
|
||||
</data>
|
||||
<data name="Polish_Language" xml:space="preserve">
|
||||
<value>Polish</value>
|
||||
</data>
|
||||
<data name="Portuguese_Brazil_Language" xml:space="preserve">
|
||||
<value>Portuguese (Brazil)</value>
|
||||
</data>
|
||||
<data name="Portuguese_Portugal_Language" xml:space="preserve">
|
||||
<value>Portuguese (Portugal)</value>
|
||||
</data>
|
||||
<data name="Russian_Language" xml:space="preserve">
|
||||
<value>Russian</value>
|
||||
</data>
|
||||
<data name="Swedish_Language" xml:space="preserve">
|
||||
<value>Swedish</value>
|
||||
</data>
|
||||
<data name="Turkish_Language" xml:space="preserve">
|
||||
<value>Turkish</value>
|
||||
</data>
|
||||
<data name="Ukrainian_Language" xml:space="preserve">
|
||||
<value>Ukrainian</value>
|
||||
</data>
|
||||
<data name="Chinese_Simplified_Language" xml:space="preserve">
|
||||
<value>Chinese (Simplified)</value>
|
||||
</data>
|
||||
<data name="Chinese_Traditional_Language" xml:space="preserve">
|
||||
<value>Chinese (Traditional)</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
@@ -145,8 +148,38 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
_fileWatcher = Helper.GetFileWatcher(string.Empty, UpdatingSettings.SettingsFile, dispatcherAction);
|
||||
}
|
||||
|
||||
InitializeLanguages();
|
||||
}
|
||||
|
||||
// Supported languages. Taken from Resources.wxs + default + en-US
|
||||
private Dictionary<string, string> langTagsAndIds = new Dictionary<string, string>
|
||||
{
|
||||
{ string.Empty, "Default_language" },
|
||||
{ "ar-SA", "Arabic_Saudi_Arabia_Language" },
|
||||
{ "cs-CZ", "Czech_Language" },
|
||||
{ "de-DE", "German_Language" },
|
||||
{ "en-US", "English_Language" },
|
||||
{ "es-ES", "Spanish_Language" },
|
||||
{ "fa-IR", "Persian_Farsi_Language" },
|
||||
{ "fr-FR", "French_Language" },
|
||||
{ "he-IL", "Hebrew_Israel_Language" },
|
||||
{ "hu-HU", "Hungarian_Language" },
|
||||
{ "it-IT", "Italian_Language" },
|
||||
{ "ja-JP", "Japanese_Language" },
|
||||
{ "ko-KR", "Korean_Language" },
|
||||
{ "nl-NL", "Dutch_Language" },
|
||||
{ "pl-PL", "Polish_Language" },
|
||||
{ "pt-BR", "Portuguese_Brazil_Language" },
|
||||
{ "pt-PT", "Portuguese_Portugal_Language" },
|
||||
{ "ru-RU", "Russian_Language" },
|
||||
{ "sv-SE", "Swedish_Language" },
|
||||
{ "tr-TR", "Turkish_Language" },
|
||||
{ "uk-UA", "Ukrainian_Language" },
|
||||
{ "zh-CN", "Chinese_Simplified_Language" },
|
||||
{ "zh-TW", "Chinese_Traditional_Language" },
|
||||
};
|
||||
|
||||
private static bool _isDevBuild;
|
||||
private bool _startup;
|
||||
private bool _isElevated;
|
||||
@@ -177,6 +210,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
private string _settingsBackupMessage;
|
||||
private string _backupRestoreMessageSeverity;
|
||||
|
||||
private int _languagesIndex;
|
||||
private int _initLanguagesIndex;
|
||||
private bool _languageChanged;
|
||||
|
||||
// Gets or sets a value indicating whether run powertoys on start-up.
|
||||
public bool Startup
|
||||
{
|
||||
@@ -740,6 +777,51 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<LanguageModel> Languages { get; } = new ObservableCollection<LanguageModel>();
|
||||
|
||||
public int LanguagesIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return _languagesIndex;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_languagesIndex != value)
|
||||
{
|
||||
_languagesIndex = value;
|
||||
OnPropertyChanged(nameof(LanguagesIndex));
|
||||
NotifyLanguageChanged();
|
||||
if (_initLanguagesIndex != value)
|
||||
{
|
||||
LanguageChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LanguageChanged = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool LanguageChanged
|
||||
{
|
||||
get
|
||||
{
|
||||
return _languageChanged;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_languageChanged != value)
|
||||
{
|
||||
_languageChanged = value;
|
||||
OnPropertyChanged(nameof(LanguageChanged));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null, bool reDoBackupDryRun = true)
|
||||
{
|
||||
// Notify UI of property change
|
||||
@@ -996,5 +1078,31 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
NotifyPropertyChanged(nameof(IsDownloadAllowed));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeLanguages()
|
||||
{
|
||||
var lang = LanguageModel.LoadSetting();
|
||||
int i = 0;
|
||||
|
||||
foreach (var item in langTagsAndIds)
|
||||
{
|
||||
Languages.Add(new LanguageModel { Tag = item.Key, ResourceID = item.Value, Language = GetResourceString(item.Value) });
|
||||
|
||||
if (item.Key.Equals(lang, StringComparison.Ordinal))
|
||||
{
|
||||
_initLanguagesIndex = i;
|
||||
LanguagesIndex = i;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private void NotifyLanguageChanged()
|
||||
{
|
||||
OutGoingLanguageSettings outsettings = new OutGoingLanguageSettings(langTagsAndIds.ElementAt(LanguagesIndex).Key);
|
||||
|
||||
SendConfigMSG(outsettings.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user