Implementing localization for en-US and pt-PT to the FileDialog. (#1625)

* Implementing localization for en-US and pt-PT to the FileDialog.

* Added a method to get all the supported cultures from the Terminal.Gui.
This commit is contained in:
BDisp
2022-03-07 06:00:47 +00:00
committed by GitHub
parent 9c8e92c2b5
commit da0ea09bed
7 changed files with 533 additions and 7 deletions

View File

@@ -13,12 +13,13 @@
// Optimizations
// - Add rendering limitation to the exposed area
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using NStack;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.IO;
namespace Terminal.Gui {
@@ -202,6 +203,13 @@ namespace Terminal.Gui {
}
}
private static List<CultureInfo> supportedCultures;
/// <summary>
/// Gets all supported cultures by the application without the invariant language.
/// </summary>
public static List<CultureInfo> SupportedCultures => supportedCultures;
static void OnQuitKeyChanged (Key oldKey)
{
foreach (var top in toplevels) {
@@ -346,6 +354,7 @@ namespace Terminal.Gui {
}
Top = topLevelFactory ();
Current = Top;
supportedCultures = GetSupportedCultures ();
_initialized = true;
}
@@ -1330,5 +1339,26 @@ namespace Terminal.Gui {
Top.BringSubviewToFront (top);
}
}
internal static List<CultureInfo> GetSupportedCultures ()
{
CultureInfo [] culture = CultureInfo.GetCultures (CultureTypes.AllCultures);
// Get the assembly
Assembly assembly = Assembly.GetExecutingAssembly ();
//Find the location of the assembly
string assemblyLocation = AppDomain.CurrentDomain.BaseDirectory;
// Find the resource file name of the assembly
string resourceFilename = $"{Path.GetFileNameWithoutExtension (assembly.Location)}.resources.dll";
// Return all culture for which satellite folder found with culture code.
return culture.Where (cultureInfo =>
assemblyLocation != null &&
Directory.Exists (Path.Combine (assemblyLocation, cultureInfo.Name)) &&
File.Exists (Path.Combine (assemblyLocation, cultureInfo.Name, resourceFilename))
).ToList ();
}
}
}

189
Terminal.Gui/Resources/Strings.Designer.cs generated Normal file
View File

@@ -0,0 +1,189 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Terminal.Gui.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Strings {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Strings() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Terminal.Gui.Resources.Strings", typeof(Strings).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to _Copy.
/// </summary>
internal static string ctxCopy {
get {
return ResourceManager.GetString("ctxCopy", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cu_t.
/// </summary>
internal static string ctxCut {
get {
return ResourceManager.GetString("ctxCut", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Delete All.
/// </summary>
internal static string ctxDeleteAll {
get {
return ResourceManager.GetString("ctxDeleteAll", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Paste.
/// </summary>
internal static string ctxPaste {
get {
return ResourceManager.GetString("ctxPaste", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Redo.
/// </summary>
internal static string ctxRedo {
get {
return ResourceManager.GetString("ctxRedo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Select All.
/// </summary>
internal static string ctxSelectAll {
get {
return ResourceManager.GetString("ctxSelectAll", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Undo.
/// </summary>
internal static string ctxUndo {
get {
return ResourceManager.GetString("ctxUndo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Directory.
/// </summary>
internal static string fdDirectory {
get {
return ResourceManager.GetString("fdDirectory", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File.
/// </summary>
internal static string fdFile {
get {
return ResourceManager.GetString("fdFile", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open.
/// </summary>
internal static string fdOpen {
get {
return ResourceManager.GetString("fdOpen", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save.
/// </summary>
internal static string fdSave {
get {
return ResourceManager.GetString("fdSave", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save as.
/// </summary>
internal static string fdSaveAs {
get {
return ResourceManager.GetString("fdSaveAs", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Select folder.
/// </summary>
internal static string fdSelectFolder {
get {
return ResourceManager.GetString("fdSelectFolder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Select Mixed.
/// </summary>
internal static string fdSelectMixed {
get {
return ResourceManager.GetString("fdSelectMixed", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: 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:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ctxCopy" xml:space="preserve">
<value>_Copiar</value>
</data>
<data name="ctxCut" xml:space="preserve">
<value>Cor_tar</value>
</data>
<data name="ctxDeleteAll" xml:space="preserve">
<value>_Apagar Tudo</value>
</data>
<data name="ctxPaste" xml:space="preserve">
<value>Co_lar</value>
</data>
<data name="ctxRedo" xml:space="preserve">
<value>_Refazer</value>
</data>
<data name="ctxSelectAll" xml:space="preserve">
<value>_Selecionar Tudo</value>
</data>
<data name="ctxUndo" xml:space="preserve">
<value>_Desfazer</value>
</data>
<data name="fdDirectory" xml:space="preserve">
<value>Diretório</value>
</data>
<data name="fdFile" xml:space="preserve">
<value>Ficheiro</value>
</data>
<data name="fdSave" xml:space="preserve">
<value>Guardar</value>
</data>
<data name="fdSaveAs" xml:space="preserve">
<value>Guardar como</value>
</data>
<data name="fdOpen" xml:space="preserve">
<value>Abrir</value>
</data>
<data name="fdSelectFolder" xml:space="preserve">
<value>Selecione pasta</value>
</data>
<data name="fdSelectMixed" xml:space="preserve">
<value>Selecione misto</value>
</data>
</root>

View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: 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:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ctxSelectAll" xml:space="preserve">
<value>_Select All</value>
</data>
<data name="ctxDeleteAll" xml:space="preserve">
<value>_Delete All</value>
</data>
<data name="ctxCopy" xml:space="preserve">
<value>_Copy</value>
</data>
<data name="ctxCut" xml:space="preserve">
<value>Cu_t</value>
</data>
<data name="ctxPaste" xml:space="preserve">
<value>_Paste</value>
</data>
<data name="ctxUndo" xml:space="preserve">
<value>_Undo</value>
</data>
<data name="ctxRedo" xml:space="preserve">
<value>_Redo</value>
</data>
<data name="fdDirectory" xml:space="preserve">
<value>Directory</value>
</data>
<data name="fdFile" xml:space="preserve">
<value>File</value>
</data>
<data name="fdSave" xml:space="preserve">
<value>Save</value>
</data>
<data name="fdSaveAs" xml:space="preserve">
<value>Save as</value>
</data>
<data name="fdOpen" xml:space="preserve">
<value>Open</value>
</data>
<data name="fdSelectFolder" xml:space="preserve">
<value>Select folder</value>
</data>
<data name="fdSelectMixed" xml:space="preserve">
<value>Select Mixed</value>
</data>
</root>

View File

@@ -17,6 +17,21 @@
<InternalsVisibleTo Include="UnitTests" />
<!-- <None Remove="ConsoleDrivers\#ConsoleDriver.cs#" /> -->
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\Strings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Strings.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\Strings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<PropertyGroup>
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
</PropertyGroup>

View File

@@ -14,6 +14,7 @@ using System.Collections.Generic;
using NStack;
using System.IO;
using System.Linq;
using Terminal.Gui.Resources;
namespace Terminal.Gui {
internal class DirListView : View {
@@ -618,7 +619,7 @@ namespace Terminal.Gui {
Add (this.message);
var msgLines = TextFormatter.MaxLines (message, Driver.Cols - 20);
this.nameDirLabel = new Label (nameDirLabel.IsEmpty ? "Directory: " : $"{nameDirLabel}: ") {
this.nameDirLabel = new Label (nameDirLabel.IsEmpty ? $"{Strings.fdDirectory}: " : $"{nameDirLabel}: ") {
X = 1,
Y = 1 + msgLines,
AutoSize = true
@@ -635,7 +636,7 @@ namespace Terminal.Gui {
};
Add (this.nameDirLabel, dirEntry);
this.nameFieldLabel = new Label (nameFieldLabel.IsEmpty ? "File: " : $"{nameFieldLabel}: ") {
this.nameFieldLabel = new Label (nameFieldLabel.IsEmpty ? $"{Strings.fdFile}: " : $"{nameFieldLabel}: ") {
X = 1,
Y = 3 + msgLines,
AutoSize = true
@@ -873,7 +874,7 @@ namespace Terminal.Gui {
/// <param name="message">The message.</param>
/// <param name="allowedTypes">The allowed types.</param>
public SaveDialog (ustring title, ustring message, List<string> allowedTypes = null)
: base (title, prompt: "Save", nameFieldLabel: "Save as:", message: message, allowedTypes) { }
: base (title, prompt: Strings.fdSave, nameFieldLabel: $"{Strings.fdSaveAs}:", message: message, allowedTypes) { }
/// <summary>
/// Gets the name of the file the user selected for saving, or null
@@ -941,8 +942,8 @@ namespace Terminal.Gui {
/// <param name="allowedTypes">The allowed types.</param>
/// <param name="openMode">The open mode.</param>
public OpenDialog (ustring title, ustring message, List<string> allowedTypes = null, OpenMode openMode = OpenMode.File) : base (title,
prompt: openMode == OpenMode.File ? "Open" : openMode == OpenMode.Directory ? "Select folder" : "Select Mixed",
nameFieldLabel: "Open", message: message, allowedTypes)
prompt: openMode == OpenMode.File ? Strings.fdOpen : openMode == OpenMode.Directory ? Strings.fdSelectFolder : Strings.fdSelectMixed,
nameFieldLabel: Strings.fdOpen, message: message, allowedTypes)
{
this.openMode = openMode;
switch (openMode) {

View File

@@ -1279,5 +1279,12 @@ namespace Terminal.Gui.Core {
win2.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Released });
Assert.Null (Toplevel.dragPosition);
}
[Fact, AutoInitShutdown]
public void GetSupportedCultures_Method ()
{
var cultures = Application.GetSupportedCultures ();
Assert.Equal (cultures.Count, Application.SupportedCultures.Count);
}
}
}