Add FallbackTable for localized strings table to redirect missing texts into other language
This commit is contained in:
@@ -113,6 +113,10 @@ namespace FlaxEditor.Windows.Assets
|
||||
[CustomEditor(typeof(FlaxEditor.CustomEditors.Editors.CultureInfoEditor))]
|
||||
public string Locale;
|
||||
|
||||
[EditorOrder(5), EditorDisplay("General"), Tooltip("The fallback language table to use for missing keys. Eg. table for 'en-GB' can point to 'en' as a fallback to prevent problem of missing localized strings.")]
|
||||
[AssetReference(true)]
|
||||
public LocalizedStringTable FallbackTable;
|
||||
|
||||
[EditorOrder(10), EditorDisplay("Entries", EditorDisplayAttribute.InlineStyle), Tooltip("The string table. Maps the message id into the localized text. For plural messages the list contains separate items for value numbers.")]
|
||||
[Collection(Spacing = 10, OverrideEditorTypeName = "FlaxEditor.Windows.Assets.LocalizedStringTableWindow+EntryEditor")]
|
||||
public Dictionary<string, string[]> Entries;
|
||||
@@ -174,6 +178,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
return;
|
||||
|
||||
_asset.Locale = _proxy.Locale;
|
||||
_asset.FallbackTable = _proxy.FallbackTable;
|
||||
_asset.Entries = _proxy.Entries;
|
||||
if (_asset.Save(_item.Path))
|
||||
{
|
||||
@@ -200,6 +205,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
_proxy = new Proxy
|
||||
{
|
||||
Locale = _asset.Locale,
|
||||
FallbackTable = _asset.FallbackTable,
|
||||
Entries = _asset.Entries,
|
||||
};
|
||||
_presenter.Select(_proxy);
|
||||
|
||||
@@ -258,20 +258,35 @@ void Localization::SetCurrentLanguageCulture(const CultureInfo& value)
|
||||
|
||||
String Localization::GetString(const String& id, const String& fallback)
|
||||
{
|
||||
String result;
|
||||
const String* result = nullptr;
|
||||
for (auto& e : Instance.LocalizedStringTables)
|
||||
{
|
||||
const auto table = e.Get();
|
||||
const auto messages = table ? table->Entries.TryGet(id) : nullptr;
|
||||
if (messages && messages->Count() != 0)
|
||||
{
|
||||
result = messages->At(0);
|
||||
result = &messages->At(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result.IsEmpty())
|
||||
result = fallback;
|
||||
return result;
|
||||
if (!result)
|
||||
{
|
||||
// Try using fallback tables
|
||||
for (auto& e : Instance.LocalizedStringTables)
|
||||
{
|
||||
const auto table = e.Get();
|
||||
const auto fallbackTable = table ? table->FallbackTable.Get() : nullptr;
|
||||
const auto messages = fallbackTable ? fallbackTable->Entries.TryGet(id) : nullptr;
|
||||
if (messages && messages->Count() != 0)
|
||||
{
|
||||
result = &messages->At(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result)
|
||||
result = &fallback;
|
||||
return *result;
|
||||
}
|
||||
|
||||
String Localization::GetPluralString(const String& id, int32 n, const String& fallback)
|
||||
@@ -289,6 +304,21 @@ String Localization::GetPluralString(const String& id, int32 n, const String& fa
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!result)
|
||||
{
|
||||
// Try using fallback tables
|
||||
for (auto& e : Instance.LocalizedStringTables)
|
||||
{
|
||||
const auto table = e.Get();
|
||||
const auto fallbackTable = table ? table->FallbackTable.Get() : nullptr;
|
||||
const auto messages = fallbackTable ? fallbackTable->Entries.TryGet(id) : nullptr;
|
||||
if (messages && messages->Count() > n)
|
||||
{
|
||||
result = &messages->At(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result)
|
||||
result = &fallback;
|
||||
return String::Format(result->GetText(), n);
|
||||
|
||||
@@ -60,6 +60,12 @@ bool LocalizedStringTable::Save(const StringView& path)
|
||||
writer.JKEY("Locale");
|
||||
writer.String(Locale);
|
||||
|
||||
if (FallbackTable.GetID().IsValid())
|
||||
{
|
||||
writer.JKEY("FallbackTable");
|
||||
writer.Guid(FallbackTable.GetID());
|
||||
}
|
||||
|
||||
writer.JKEY("Entries");
|
||||
writer.StartObject();
|
||||
for (auto& e : Entries)
|
||||
@@ -102,6 +108,9 @@ Asset::LoadResult LocalizedStringTable::loadAsset()
|
||||
return result;
|
||||
|
||||
JsonTools::GetString(Locale, *Data, "Locale");
|
||||
Guid fallbackTable = Guid::Empty;
|
||||
JsonTools::GetGuid(fallbackTable, *Data, "FallbackTable");
|
||||
FallbackTable = fallbackTable;
|
||||
const auto entriesMember = SERIALIZE_FIND_MEMBER((*Data), "Entries");
|
||||
if (entriesMember != Data->MemberEnd() && entriesMember->value.IsObject())
|
||||
{
|
||||
@@ -134,5 +143,6 @@ void LocalizedStringTable::unload(bool isReloading)
|
||||
JsonAssetBase::unload(isReloading);
|
||||
|
||||
Locale.Clear();
|
||||
FallbackTable = nullptr;
|
||||
Entries.Clear();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Engine/Content/JsonAsset.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#include "Engine/Scripting/SoftObjectReference.h"
|
||||
|
||||
/// <summary>
|
||||
/// Contains localized strings table for a given culture.
|
||||
@@ -14,17 +15,24 @@ API_CLASS(NoSpawn) class FLAXENGINE_API LocalizedStringTable : public JsonAssetB
|
||||
{
|
||||
DECLARE_ASSET_HEADER(LocalizedStringTable);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The locale of the localized string table (eg. pl-PL).
|
||||
/// </summary>
|
||||
API_FIELD() String Locale;
|
||||
|
||||
/// <summary>
|
||||
/// The fallback language table to use for missing keys. Eg. table for 'en-GB' can point to 'en' as a fallback to prevent problem of missing localized strings.
|
||||
/// </summary>
|
||||
API_FIELD() SoftObjectReference<LocalizedStringTable> FallbackTable;
|
||||
|
||||
/// <summary>
|
||||
/// The string table. Maps the message id into the localized text. For plural messages the list contains separate items for value numbers.
|
||||
/// </summary>
|
||||
API_FIELD() Dictionary<String, Array<String>> Entries;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Adds the localized string to the table.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user