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))]
|
[CustomEditor(typeof(FlaxEditor.CustomEditors.Editors.CultureInfoEditor))]
|
||||||
public string Locale;
|
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.")]
|
[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")]
|
[Collection(Spacing = 10, OverrideEditorTypeName = "FlaxEditor.Windows.Assets.LocalizedStringTableWindow+EntryEditor")]
|
||||||
public Dictionary<string, string[]> Entries;
|
public Dictionary<string, string[]> Entries;
|
||||||
@@ -174,6 +178,7 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_asset.Locale = _proxy.Locale;
|
_asset.Locale = _proxy.Locale;
|
||||||
|
_asset.FallbackTable = _proxy.FallbackTable;
|
||||||
_asset.Entries = _proxy.Entries;
|
_asset.Entries = _proxy.Entries;
|
||||||
if (_asset.Save(_item.Path))
|
if (_asset.Save(_item.Path))
|
||||||
{
|
{
|
||||||
@@ -200,6 +205,7 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
_proxy = new Proxy
|
_proxy = new Proxy
|
||||||
{
|
{
|
||||||
Locale = _asset.Locale,
|
Locale = _asset.Locale,
|
||||||
|
FallbackTable = _asset.FallbackTable,
|
||||||
Entries = _asset.Entries,
|
Entries = _asset.Entries,
|
||||||
};
|
};
|
||||||
_presenter.Select(_proxy);
|
_presenter.Select(_proxy);
|
||||||
|
|||||||
@@ -258,20 +258,35 @@ void Localization::SetCurrentLanguageCulture(const CultureInfo& value)
|
|||||||
|
|
||||||
String Localization::GetString(const String& id, const String& fallback)
|
String Localization::GetString(const String& id, const String& fallback)
|
||||||
{
|
{
|
||||||
String result;
|
const String* result = nullptr;
|
||||||
for (auto& e : Instance.LocalizedStringTables)
|
for (auto& e : Instance.LocalizedStringTables)
|
||||||
{
|
{
|
||||||
const auto table = e.Get();
|
const auto table = e.Get();
|
||||||
const auto messages = table ? table->Entries.TryGet(id) : nullptr;
|
const auto messages = table ? table->Entries.TryGet(id) : nullptr;
|
||||||
if (messages && messages->Count() != 0)
|
if (messages && messages->Count() != 0)
|
||||||
{
|
{
|
||||||
result = messages->At(0);
|
result = &messages->At(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result.IsEmpty())
|
if (!result)
|
||||||
result = fallback;
|
{
|
||||||
return 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)
|
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;
|
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)
|
if (!result)
|
||||||
result = &fallback;
|
result = &fallback;
|
||||||
return String::Format(result->GetText(), n);
|
return String::Format(result->GetText(), n);
|
||||||
|
|||||||
@@ -60,6 +60,12 @@ bool LocalizedStringTable::Save(const StringView& path)
|
|||||||
writer.JKEY("Locale");
|
writer.JKEY("Locale");
|
||||||
writer.String(Locale);
|
writer.String(Locale);
|
||||||
|
|
||||||
|
if (FallbackTable.GetID().IsValid())
|
||||||
|
{
|
||||||
|
writer.JKEY("FallbackTable");
|
||||||
|
writer.Guid(FallbackTable.GetID());
|
||||||
|
}
|
||||||
|
|
||||||
writer.JKEY("Entries");
|
writer.JKEY("Entries");
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
for (auto& e : Entries)
|
for (auto& e : Entries)
|
||||||
@@ -102,6 +108,9 @@ Asset::LoadResult LocalizedStringTable::loadAsset()
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
JsonTools::GetString(Locale, *Data, "Locale");
|
JsonTools::GetString(Locale, *Data, "Locale");
|
||||||
|
Guid fallbackTable = Guid::Empty;
|
||||||
|
JsonTools::GetGuid(fallbackTable, *Data, "FallbackTable");
|
||||||
|
FallbackTable = fallbackTable;
|
||||||
const auto entriesMember = SERIALIZE_FIND_MEMBER((*Data), "Entries");
|
const auto entriesMember = SERIALIZE_FIND_MEMBER((*Data), "Entries");
|
||||||
if (entriesMember != Data->MemberEnd() && entriesMember->value.IsObject())
|
if (entriesMember != Data->MemberEnd() && entriesMember->value.IsObject())
|
||||||
{
|
{
|
||||||
@@ -134,5 +143,6 @@ void LocalizedStringTable::unload(bool isReloading)
|
|||||||
JsonAssetBase::unload(isReloading);
|
JsonAssetBase::unload(isReloading);
|
||||||
|
|
||||||
Locale.Clear();
|
Locale.Clear();
|
||||||
|
FallbackTable = nullptr;
|
||||||
Entries.Clear();
|
Entries.Clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "Engine/Content/JsonAsset.h"
|
#include "Engine/Content/JsonAsset.h"
|
||||||
#include "Engine/Core/Collections/Array.h"
|
#include "Engine/Core/Collections/Array.h"
|
||||||
#include "Engine/Core/Collections/Dictionary.h"
|
#include "Engine/Core/Collections/Dictionary.h"
|
||||||
|
#include "Engine/Scripting/SoftObjectReference.h"
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains localized strings table for a given culture.
|
/// 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);
|
DECLARE_ASSET_HEADER(LocalizedStringTable);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The locale of the localized string table (eg. pl-PL).
|
/// The locale of the localized string table (eg. pl-PL).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FIELD() String Locale;
|
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>
|
/// <summary>
|
||||||
/// The string table. Maps the message id into the localized text. For plural messages the list contains separate items for value numbers.
|
/// The string table. Maps the message id into the localized text. For plural messages the list contains separate items for value numbers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FIELD() Dictionary<String, Array<String>> Entries;
|
API_FIELD() Dictionary<String, Array<String>> Entries;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the localized string to the table.
|
/// Adds the localized string to the table.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user