|
1 | 1 | #region Copyright and License
|
2 | 2 |
|
3 | 3 | /*
|
4 |
| - * Xecrets Ez - Copyright © 2022-2024, Svante Seleborg, All Rights Reserved. |
| 4 | + * Xecrets Ez - Copyright © 2022-2025 Svante Seleborg, All Rights Reserved. |
5 | 5 | *
|
6 | 6 | * This code file is part of Xecrets Ez - A cross platform desktop application
|
7 | 7 | * for encryption, decryption and other file operations based on Xecrets Cli.
|
|
38 | 38 |
|
39 | 39 | using System.Globalization;
|
40 | 40 |
|
41 |
| -namespace Xecrets.Localization |
| 41 | +namespace Xecrets.Localization; |
| 42 | + |
| 43 | +/// <summary> |
| 44 | +/// Localizes strings using a <see cref="ITranslationsProvider"/>. |
| 45 | +/// </summary> |
| 46 | +/// <param name="translationsProvider"></param> |
| 47 | +/// <param name="location"></param> |
| 48 | +/// <param name="culture"></param> |
| 49 | +public sealed class POStringLocalizer(ITranslationsProvider translationsProvider, string location, CultureInfo? culture = null) : IStringLocalizer |
42 | 50 | {
|
| 51 | + private readonly CultureInfo _culture = culture ?? CultureInfo.CurrentUICulture; |
| 52 | + |
43 | 53 | /// <summary>
|
44 |
| - /// Localizes strings using a <see cref="ITranslationsProvider"/>. |
| 54 | + /// Translates a string by name, falling back to the name if no translation is found. |
45 | 55 | /// </summary>
|
46 |
| - /// <param name="translationsProvider"></param> |
47 |
| - /// <param name="location"></param> |
48 |
| - /// <param name="culture"></param> |
49 |
| - public sealed class POStringLocalizer(ITranslationsProvider translationsProvider, string location, CultureInfo? culture = null) : IStringLocalizer |
| 56 | + /// <param name="name">The string to translate, typically the english original.</param> |
| 57 | + /// <returns>A translated string.</returns> |
| 58 | + public LocalizedString this[string name] |
50 | 59 | {
|
51 |
| - private readonly CultureInfo _culture = culture ?? CultureInfo.CurrentUICulture; |
52 |
| - |
53 |
| - /// <summary> |
54 |
| - /// Translates a string by name, falling back to the name if no translation is found. |
55 |
| - /// </summary> |
56 |
| - /// <param name="name">The string to translate, typically the english original.</param> |
57 |
| - /// <returns>A translated string.</returns> |
58 |
| - public LocalizedString this[string name] |
| 60 | + get |
59 | 61 | {
|
60 |
| - get |
61 |
| - { |
62 |
| - bool resourceNotFound = !TryGetTranslation(name, out var searchedLocation, out var value); |
63 |
| - return new LocalizedString(name, value!, resourceNotFound, searchedLocation); |
64 |
| - } |
| 62 | + bool resourceNotFound = !TryGetTranslation(name, out var searchedLocation, out var value); |
| 63 | + return new LocalizedString(name, value!, resourceNotFound, searchedLocation); |
65 | 64 | }
|
| 65 | + } |
66 | 66 |
|
67 |
| - /// <summary> |
68 |
| - /// Translates a string by name, falling back to the name if no translation is found. |
69 |
| - /// Also formats the string with the provided arguments. |
70 |
| - /// </summary> |
71 |
| - /// <param name="name">The string to translate, typically the english original.</param> |
72 |
| - /// <param name="arguments">Arguments passed to string.Format()</param> |
73 |
| - /// <returns>A translated string.</returns> |
74 |
| - public LocalizedString this[string name, params object[] arguments] |
| 67 | + /// <summary> |
| 68 | + /// Translates a string by name, falling back to the name if no translation is found. |
| 69 | + /// Also formats the string with the provided arguments. |
| 70 | + /// </summary> |
| 71 | + /// <param name="name">The string to translate, typically the english original.</param> |
| 72 | + /// <param name="arguments">Arguments passed to string.Format()</param> |
| 73 | + /// <returns>A translated string.</returns> |
| 74 | + public LocalizedString this[string name, params object[] arguments] |
| 75 | + { |
| 76 | + get |
75 | 77 | {
|
76 |
| - get |
77 |
| - { |
78 |
| - bool resourceNotFound = !TryGetTranslation(name, out string searchedLocation, out string value); |
79 |
| - return new LocalizedString(name, string.Format(value!, arguments), resourceNotFound, searchedLocation); |
80 |
| - } |
| 78 | + bool resourceNotFound = !TryGetTranslation(name, out string searchedLocation, out string value); |
| 79 | + return new LocalizedString(name, string.Format(value!, arguments), resourceNotFound, searchedLocation); |
81 | 80 | }
|
| 81 | + } |
82 | 82 |
|
83 |
| - /// <summary> |
84 |
| - /// Try to get a translation for a given name. |
85 |
| - /// </summary> |
86 |
| - /// <param name="name">The name of the string to get.</param> |
87 |
| - /// <param name="searchedLocation">Where we're looking for the translation.</param> |
88 |
| - /// <param name="value">The translated value, or falls back to name.</param> |
89 |
| - /// <returns>true if a translation was found.</returns> |
90 |
| - public bool TryGetTranslation(string name, out string searchedLocation, out string value) |
| 83 | + /// <summary> |
| 84 | + /// Try to get a translation for a given name. |
| 85 | + /// </summary> |
| 86 | + /// <param name="name">The name of the string to get.</param> |
| 87 | + /// <param name="searchedLocation">Where we're looking for the translation.</param> |
| 88 | + /// <param name="value">The translated value, or falls back to name.</param> |
| 89 | + /// <returns>true if a translation was found.</returns> |
| 90 | + public bool TryGetTranslation(string name, out string searchedLocation, out string value) |
| 91 | + { |
| 92 | + bool wasFound = TryInternal(location, name, out searchedLocation, out value); |
| 93 | + value = value.Replace(@"\n", Environment.NewLine); |
| 94 | + return wasFound; |
| 95 | + } |
| 96 | + |
| 97 | + private bool TryInternal(string location, string name, out string searchedLocation, out string value) |
| 98 | + { |
| 99 | + searchedLocation = location; |
| 100 | + |
| 101 | + IReadOnlyDictionary<string, POCatalog> catalogs = translationsProvider.GetCatalogs(); |
| 102 | + POCatalog? catalog = GetCatalog(catalogs); |
| 103 | + if (catalog == null) |
91 | 104 | {
|
92 |
| - bool wasFound = TryInternal(location, name, out searchedLocation, out value); |
93 |
| - value = value.Replace(@"\n", Environment.NewLine); |
94 |
| - return wasFound; |
| 105 | + value = name; |
| 106 | + return false; |
95 | 107 | }
|
96 | 108 |
|
97 |
| - private bool TryInternal(string location, string name, out string searchedLocation, out string value) |
| 109 | + POKey key = new(name.Replace("\r\n", "\n")); |
| 110 | + string? translation = catalog.GetTranslation(key); |
| 111 | + if (translation == null) |
98 | 112 | {
|
99 |
| - searchedLocation = location; |
| 113 | + catalogs.TryGetValue("en-US", out POCatalog? englishCatalog); |
| 114 | + translation = englishCatalog?.GetTranslation(key) ?? key.Id; |
| 115 | + } |
100 | 116 |
|
101 |
| - IReadOnlyDictionary<string, POCatalog> catalogs = translationsProvider.GetCatalogs(); |
102 |
| - POCatalog? catalog = GetCatalog(catalogs); |
103 |
| - if (catalog == null) |
| 117 | + value = translation; |
| 118 | + return value != key.Id; |
| 119 | + } |
| 120 | + |
| 121 | + private POCatalog? GetCatalog(IReadOnlyDictionary<string, POCatalog> catalogs) |
| 122 | + { |
| 123 | + CultureInfo culture = _culture; |
| 124 | + while (true) |
| 125 | + { |
| 126 | + if (catalogs.TryGetValue(culture.Name, out POCatalog? catalog)) |
104 | 127 | {
|
105 |
| - value = name; |
106 |
| - return false; |
| 128 | + return catalog; |
107 | 129 | }
|
108 | 130 |
|
109 |
| - POKey key = new(name.Replace("\r\n", "\n")); |
110 |
| - string? translation = catalog.GetTranslation(key); |
111 |
| - if (translation == null) |
| 131 | + CultureInfo parentCulture = culture.Parent; |
| 132 | + if (culture == parentCulture) |
112 | 133 | {
|
113 | 134 | catalogs.TryGetValue("en-US", out POCatalog? englishCatalog);
|
114 |
| - translation = englishCatalog?.GetTranslation(key) ?? key.Id; |
| 135 | + return englishCatalog; |
115 | 136 | }
|
116 | 137 |
|
117 |
| - value = translation; |
118 |
| - return value != key.Id; |
119 |
| - } |
120 |
| - |
121 |
| - private POCatalog? GetCatalog(IReadOnlyDictionary<string, POCatalog> catalogs) |
122 |
| - { |
123 |
| - CultureInfo culture = _culture; |
124 |
| - while (true) |
125 |
| - { |
126 |
| - if (catalogs.TryGetValue(culture.Name, out POCatalog? catalog)) |
127 |
| - { |
128 |
| - return catalog; |
129 |
| - } |
130 |
| - |
131 |
| - CultureInfo parentCulture = culture.Parent; |
132 |
| - if (culture == parentCulture) |
133 |
| - { |
134 |
| - catalogs.TryGetValue("en-US", out POCatalog? englishCatalog); |
135 |
| - return englishCatalog; |
136 |
| - } |
137 |
| - |
138 |
| - culture = parentCulture; |
139 |
| - } |
| 138 | + culture = parentCulture; |
140 | 139 | }
|
| 140 | + } |
141 | 141 |
|
142 |
| - /// <summary> |
143 |
| - /// Get all strings for the current culture. |
144 |
| - /// </summary> |
145 |
| - /// <param name="includeParentCultures"></param> |
146 |
| - /// <returns></returns> |
147 |
| - public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures) |
| 142 | + /// <summary> |
| 143 | + /// Get all strings for the current culture. |
| 144 | + /// </summary> |
| 145 | + /// <param name="includeParentCultures"></param> |
| 146 | + /// <returns></returns> |
| 147 | + public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures) |
| 148 | + { |
| 149 | + IReadOnlyDictionary<string, POCatalog> catalogs = translationsProvider.GetCatalogs(); |
| 150 | + CultureInfo culture = _culture; |
| 151 | + do |
148 | 152 | {
|
149 |
| - IReadOnlyDictionary<string, POCatalog> catalogs = translationsProvider.GetCatalogs(); |
150 |
| - CultureInfo culture = _culture; |
151 |
| - do |
| 153 | + if (catalogs.TryGetValue(culture.Name, out var catalog)) |
152 | 154 | {
|
153 |
| - if (catalogs.TryGetValue(culture.Name, out var catalog)) |
| 155 | + foreach (IPOEntry? entry in catalog) |
154 | 156 | {
|
155 |
| - foreach (IPOEntry? entry in catalog) |
| 157 | + if (entry.Count > 0) |
156 | 158 | {
|
157 |
| - if (entry.Count > 0) |
158 |
| - { |
159 |
| - yield return new LocalizedString(entry.Key.Id, entry[0], resourceNotFound: false, location); |
160 |
| - } |
| 159 | + yield return new LocalizedString(entry.Key.Id, entry[0], resourceNotFound: false, location); |
161 | 160 | }
|
162 | 161 | }
|
| 162 | + } |
163 | 163 |
|
164 |
| - CultureInfo parentCulture = culture.Parent; |
165 |
| - if (culture == parentCulture) |
166 |
| - { |
167 |
| - break; |
168 |
| - } |
169 |
| - |
170 |
| - culture = parentCulture; |
| 164 | + CultureInfo parentCulture = culture.Parent; |
| 165 | + if (culture == parentCulture) |
| 166 | + { |
| 167 | + break; |
171 | 168 | }
|
172 |
| - while (includeParentCultures); |
| 169 | + |
| 170 | + culture = parentCulture; |
173 | 171 | }
|
| 172 | + while (includeParentCultures); |
174 | 173 | }
|
175 | 174 | }
|
0 commit comments