Repository navigation
Expand file tree
/
Copy pathLocalization.cs
More file actions
147 lines (126 loc) · 4.93 KB
/
Copy pathLocalization.cs
File metadata and controls
147 lines (126 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
namespace MicaPDF
{
/// <summary>
/// Loads string catalogs from Strings/{lang}.json next to the exe.
/// Add a language by dropping another JSON file and registering it in AvailableLanguages / Settings.
/// </summary>
public static class Loc
{
public const string System = "System";
public const string English = "en";
public const string Italian = "it";
private static readonly Dictionary<string, Dictionary<string, string>> Catalogs =
new(StringComparer.OrdinalIgnoreCase);
private static Dictionary<string, string> _fallback = new(StringComparer.OrdinalIgnoreCase);
private static string _active = English;
public static string ActiveLanguage => _active;
public static event EventHandler? Changed;
public static IReadOnlyList<(string Id, string DisplayName)> AvailableLanguages { get; } =
[
(System, "System"),
(English, "English"),
(Italian, "Italiano")
];
static Loc()
{
LoadCatalog(English);
LoadCatalog(Italian);
if (Catalogs.TryGetValue(English, out var en))
_fallback = en;
}
private static string StringsDirectory
{
get
{
var baseDir = AppContext.BaseDirectory;
var beside = Path.Combine(baseDir, "Strings");
if (Directory.Exists(beside))
return beside;
// Dev fallback when running from project tree
var project = Path.GetFullPath(Path.Combine(baseDir, "..", "..", "..", "..", "Strings"));
return Directory.Exists(project) ? project : beside;
}
}
private static void LoadCatalog(string languageId)
{
try
{
var path = Path.Combine(StringsDirectory, languageId + ".json");
if (!File.Exists(path))
return;
var json = File.ReadAllText(path, Encoding.UTF8);
var map = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
if (map == null || map.Count == 0)
return;
Catalogs[languageId] = new Dictionary<string, string>(map, StringComparer.OrdinalIgnoreCase);
}
catch
{
// Missing/invalid catalog: fall back to English keys or key names.
}
}
public static string ResolveLanguageId(string? preference)
{
if (string.Equals(preference, English, StringComparison.OrdinalIgnoreCase))
return English;
if (string.Equals(preference, Italian, StringComparison.OrdinalIgnoreCase))
return Italian;
try
{
var langs = Windows.System.UserProfile.GlobalizationPreferences.Languages;
var primary = langs?.FirstOrDefault() ?? CultureInfo.CurrentUICulture.Name;
if (!string.IsNullOrEmpty(primary) &&
primary.StartsWith("it", StringComparison.OrdinalIgnoreCase))
return Italian;
}
catch
{
if (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName
.Equals("it", StringComparison.OrdinalIgnoreCase))
return Italian;
}
return English;
}
public static void Apply(string? preference)
{
var resolved = ResolveLanguageId(preference);
if (string.Equals(_active, resolved, StringComparison.OrdinalIgnoreCase))
return;
_active = resolved;
try
{
var culture = CultureInfo.GetCultureInfo(resolved);
CultureInfo.CurrentUICulture = culture;
CultureInfo.CurrentCulture = culture;
}
catch
{
}
Changed?.Invoke(null, EventArgs.Empty);
}
public static string Get(string key)
{
if (Catalogs.TryGetValue(_active, out var map) && map.TryGetValue(key, out var value))
return value;
if (_fallback.TryGetValue(key, out var fallback))
return fallback;
return key;
}
public static string Format(string key, params object[] args) =>
string.Format(CultureInfo.CurrentUICulture, Get(key), args);
public static string MenuTitle(string tag) => Get("menu." + tag);
public static string? MenuHint(string tag)
{
var key = "menu." + tag + ".hint";
var value = Get(key);
return string.Equals(value, key, StringComparison.Ordinal) ? null : value;
}
}
}