Browse Source

Merge pull request #3612 from BDisp/v2_3611_localization-self-contained-single-file-fix

Fixes #3611. Localization not working on self-contained single-file.
Tig 1 year ago
parent
commit
66ac07a301

+ 24 - 2
SelfContained/Program.cs

@@ -1,6 +1,8 @@
-// This is a simple example application for a self-contained single file.
+// This is a test application for a self-contained single file.
 
 
+using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
 using Terminal.Gui;
 using Terminal.Gui;
 
 
 namespace SelfContained;
 namespace SelfContained;
@@ -10,7 +12,27 @@ public static class Program
     [RequiresUnreferencedCode ("Calls Terminal.Gui.Application.Run<T>(Func<Exception, Boolean>, ConsoleDriver)")]
     [RequiresUnreferencedCode ("Calls Terminal.Gui.Application.Run<T>(Func<Exception, Boolean>, ConsoleDriver)")]
     private static void Main (string [] args)
     private static void Main (string [] args)
     {
     {
-        Application.Run<ExampleWindow> ().Dispose ();
+        Application.Init ();
+
+        #region The code in this region is not intended for use in a self-contained single-file. It's just here to make sure there is no functionality break with localization in Terminal.Gui using single-file
+
+        if (Equals (Thread.CurrentThread.CurrentUICulture, CultureInfo.InvariantCulture) && Application.SupportedCultures.Count == 0)
+        {
+            Debug.Assert (Application.SupportedCultures.Count == 0);
+        }
+        else
+        {
+            Debug.Assert (Application.SupportedCultures.Count == 4);
+            Debug.Assert (Equals (CultureInfo.CurrentCulture, Thread.CurrentThread.CurrentUICulture));
+        }
+
+        #endregion
+
+        ExampleWindow app = new ();
+        Application.Run (app);
+
+        // Dispose the app object before shutdown
+        app.Dispose ();
 
 
         // Before the application exits, reset Terminal.Gui for clean shutdown
         // Before the application exits, reset Terminal.Gui for clean shutdown
         Application.Shutdown ();
         Application.Shutdown ();

+ 1 - 1
SelfContained/README.md

@@ -1,6 +1,6 @@
 # Terminal.Gui C# SelfContained
 # Terminal.Gui C# SelfContained
 
 
-This example shows how to use the `Terminal.Gui` library to create a simple `self-contained` `single file` GUI application in C#.
+This project aims to test the `Terminal.Gui` library to create a simple `self-contained` `single-file` GUI application in C#, ensuring that all its features are available.
 
 
 With `Debug` the `.csproj` is used and with `Release` the latest `nuget package` is used, either in `Solution Configurations` or in `Profile Publish`.
 With `Debug` the `.csproj` is used and with `Release` the latest `nuget package` is used, either in `Solution Configurations` or in `Profile Publish`.
 
 

+ 1 - 1
SelfContained/SelfContained.csproj

@@ -8,7 +8,7 @@
     <PublishTrimmed>true</PublishTrimmed>
     <PublishTrimmed>true</PublishTrimmed>
     <TrimMode>Link</TrimMode>
     <TrimMode>Link</TrimMode>
     <PublishSingleFile>true</PublishSingleFile>
     <PublishSingleFile>true</PublishSingleFile>
-    <InvariantGlobalization>true</InvariantGlobalization>
+    <InvariantGlobalization>false</InvariantGlobalization>
     <DebugType>embedded</DebugType>
     <DebugType>embedded</DebugType>
   </PropertyGroup>
   </PropertyGroup>
 
 

+ 32 - 10
Terminal.Gui/Application/Application.cs

@@ -48,7 +48,7 @@ public static partial class Application
 
 
     internal static List<CultureInfo> GetSupportedCultures ()
     internal static List<CultureInfo> GetSupportedCultures ()
     {
     {
-        CultureInfo [] culture = CultureInfo.GetCultures (CultureTypes.AllCultures);
+        CultureInfo [] cultures = CultureInfo.GetCultures (CultureTypes.AllCultures);
 
 
         // Get the assembly
         // Get the assembly
         var assembly = Assembly.GetExecutingAssembly ();
         var assembly = Assembly.GetExecutingAssembly ();
@@ -57,15 +57,37 @@ public static partial class Application
         string assemblyLocation = AppDomain.CurrentDomain.BaseDirectory;
         string assemblyLocation = AppDomain.CurrentDomain.BaseDirectory;
 
 
         // Find the resource file name of the assembly
         // Find the resource file name of the assembly
-        var resourceFilename = $"{Path.GetFileNameWithoutExtension (AppContext.BaseDirectory)}.resources.dll";
-
-        // Return all culture for which satellite folder found with culture code.
-        return culture.Where (
-                              cultureInfo =>
-                                  Directory.Exists (Path.Combine (assemblyLocation, cultureInfo.Name))
-                                  && File.Exists (Path.Combine (assemblyLocation, cultureInfo.Name, resourceFilename))
-                             )
-                      .ToList ();
+        var resourceFilename = $"{assembly.GetName ().Name}.resources.dll";
+
+        if (cultures.Length > 1 && Directory.Exists (Path.Combine (assemblyLocation, "pt-PT")))
+        {
+            // Return all culture for which satellite folder found with culture code.
+            return cultures.Where (
+                                  cultureInfo =>
+                                      Directory.Exists (Path.Combine (assemblyLocation, cultureInfo.Name))
+                                      && File.Exists (Path.Combine (assemblyLocation, cultureInfo.Name, resourceFilename))
+                                 )
+                          .ToList ();
+        }
+
+        // It's called from a self-contained single.file.
+        try
+        {
+            // <InvariantGlobalization>false</InvariantGlobalization>
+            return
+            [
+                new ("fr-FR"),
+                new ("ja-JP"),
+                new ("pt-PT"),
+                new ("zh-Hans")
+            ];
+        }
+        catch (CultureNotFoundException)
+        {
+            // <InvariantGlobalization>true</InvariantGlobalization>
+            // Only the invariant culture is supported in globalization-invariant mode.
+            return [];
+        }
     }
     }
 
 
     /// <summary>
     /// <summary>

+ 1 - 0
UnitTests/Application/ApplicationTests.cs

@@ -193,6 +193,7 @@ public class ApplicationTests
             // Internal properties
             // Internal properties
             Assert.False (Application._initialized);
             Assert.False (Application._initialized);
             Assert.Equal (Application.GetSupportedCultures (), Application.SupportedCultures);
             Assert.Equal (Application.GetSupportedCultures (), Application.SupportedCultures);
+            Assert.Equal (4, Application.SupportedCultures.Count);
             Assert.False (Application._forceFakeConsole);
             Assert.False (Application._forceFakeConsole);
             Assert.Equal (-1, Application._mainThreadId);
             Assert.Equal (-1, Application._mainThreadId);
             Assert.Empty (Application._topLevels);
             Assert.Empty (Application._topLevels);