From 6cf7c49f34eac8edd18012d41d1f49a149fb1f5a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 15 Aug 2021 01:25:56 -0400 Subject: add GetInAllLocales to translation API --- .../Framework/ModHelpers/TranslationHelper.cs | 6 ++ src/SMAPI/Framework/Translator.cs | 65 ++++++++++++++++++---- 2 files changed, 60 insertions(+), 11 deletions(-) (limited to 'src/SMAPI/Framework') diff --git a/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs b/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs index a88ca9c9..869664fe 100644 --- a/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs @@ -55,6 +55,12 @@ namespace StardewModdingAPI.Framework.ModHelpers return this.Translator.Get(key, tokens); } + /// + public IDictionary GetInAllLocales(string key, bool withFallback = false) + { + return this.Translator.GetInAllLocales(key, withFallback); + } + /// Set the translations to use. /// The translations to use. internal TranslationHelper SetTranslations(IDictionary> translations) diff --git a/src/SMAPI/Framework/Translator.cs b/src/SMAPI/Framework/Translator.cs index 11ec983b..4492b17f 100644 --- a/src/SMAPI/Framework/Translator.cs +++ b/src/SMAPI/Framework/Translator.cs @@ -46,18 +46,10 @@ namespace StardewModdingAPI.Framework this.LocaleEnum = localeEnum; this.ForLocale = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (string next in this.GetRelevantLocales(this.Locale)) + foreach (string key in this.GetAllKeysRaw()) { - // skip if locale not defined - if (!this.All.TryGetValue(next, out IDictionary translations)) - continue; - - // add missing translations - foreach (var pair in translations) - { - if (!this.ForLocale.ContainsKey(pair.Key)) - this.ForLocale.Add(pair.Key, new Translation(this.Locale, pair.Key, pair.Value)); - } + string text = this.GetRaw(key, locale, withFallback: true); + this.ForLocale.Add(key, new Translation(this.Locale, key, text)); } } @@ -83,6 +75,25 @@ namespace StardewModdingAPI.Framework return this.Get(key).Tokens(tokens); } + /// Get a translation in every locale for which it's defined. + /// The translation key. + /// Whether to add duplicate translations for locale fallback. For example, if a translation is defined in default.json but not fr.json, setting this to true will add a fr entry which duplicates the default text. + public IDictionary GetInAllLocales(string key, bool withFallback) + { + IDictionary translations = new Dictionary(); + + foreach (var localeSet in this.All) + { + string locale = localeSet.Key; + string text = this.GetRaw(key, locale, withFallback); + + if (text != null) + translations[locale] = new Translation(locale, key, text); + } + + return translations; + } + /// Set the translations to use. /// The translations to use. internal Translator SetTranslations(IDictionary> translations) @@ -102,6 +113,38 @@ namespace StardewModdingAPI.Framework /********* ** Private methods *********/ + /// Get all translation keys in the underlying translation data, ignoring the cache. + private IEnumerable GetAllKeysRaw() + { + return new HashSet( + this.All.SelectMany(p => p.Value.Keys), + StringComparer.OrdinalIgnoreCase + ); + } + + /// Get a translation from the underlying translation data, ignoring the cache. + /// The translation key. + /// The locale to get. + /// Whether to add duplicate translations for locale fallback. For example, if a translation is defined in default.json but not fr.json, setting this to true will add a fr entry which duplicates the default text. + private string GetRaw(string key, string locale, bool withFallback) + { + foreach (string next in this.GetRelevantLocales(locale)) + { + string translation = null; + bool hasTranslation = + this.All.TryGetValue(next, out IDictionary translations) + && translations.TryGetValue(key, out translation); + + if (hasTranslation) + return translation; + + if (!withFallback) + break; + } + + return null; + } + /// Get the locales which can provide translations for the given locale, in precedence order. /// The locale for which to find valid locales. private IEnumerable GetRelevantLocales(string locale) -- cgit