// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using UnityEngine;
using UnityEngine.Internal;
using UnityEngine.Assertions;
using System;
using System.Collections.Generic;
using System.Reflection;
using JetBrains.Annotations;
namespace UnityEditor
{
///
/// This provides Localization function.
///
public static class L10n
{
static object lockObject = new object();
static Dictionary s_GroupNames = new Dictionary(128);
private readonly struct LocKey : IEquatable
{
[NotNull] public readonly string defaultString;
[NotNull] public readonly string groupName;
public LocKey(string _defaultString, string _groupName)
{
defaultString = _defaultString ?? string.Empty;
groupName = _groupName ?? string.Empty;
}
public bool Equals(LocKey other)
{
return defaultString == other.defaultString && groupName == other.groupName;
}
public override bool Equals(object obj)
{
return obj is LocKey other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
return (defaultString.GetHashCode() * 397) ^ groupName.GetHashCode();
}
}
}
static Dictionary s_LocalizedStringCache = new Dictionary(10 << 10);
internal static void ClearCache()
{
lock (lockObject)
s_LocalizedStringCache.Clear();
}
internal static string GetGroupName(System.Reflection.Assembly assembly)
{
if (assembly == null)
return null;
lock (lockObject)
{
if (!s_GroupNames.TryGetValue(assembly, out var name))
{
var attrobjs = assembly.GetCustomAttributes(typeof(LocalizationAttribute), true /* inherit */);
if (attrobjs.Length > 0 && attrobjs[0] != null)
{
var locAttr = (LocalizationAttribute)attrobjs[0];
string locGroupName = locAttr.locGroupName;
if (locGroupName == null)
locGroupName = assembly.GetName().Name;
name = locGroupName;
s_GroupNames[assembly] = name;
}
else
{
s_GroupNames[assembly] = null;
}
}
return name;
}
}
///
/// Get the translation for the given argument.
/// The original string to be translated.
///
public static string Tr(string str)
{
return Tr(str, Assembly.GetCallingAssembly());
}
internal static string Tr(string str, object context)
{
return Tr(str, context?.GetType().Assembly);
}
internal static string Tr(string str, Assembly groupAssembly)
{
if (!LocalizationDatabase.enableEditorLocalization)
return str;
if (string.IsNullOrEmpty(str))
return str;
lock (lockObject)
{
var groupName = GetGroupName(groupAssembly);
var key = new LocKey(str, groupName);
if (s_LocalizedStringCache.TryGetValue(key, out var localized))
return localized;
localized = (groupName != null)
? LocalizationDatabase.GetLocalizedStringWithGroupName(str, groupName)
: LocalizationDatabase.GetLocalizedString(str);
s_LocalizedStringCache[key] = localized;
return localized;
}
}
///
/// Get the translation array for the given argument array.
/// The original strings to be translated.
///
public static string[] Tr(string[] str_list)
{
var res = new string[str_list.Length];
for (var i = 0; i < res.Length; ++i)
res[i] = Tr(str_list[i]);
return res;
}
///
/// Get the translation for the given argument.
/// The original string to be translated.
/// The specified group name for the translation.
///
public static string Tr(string str, string groupName)
{
var new_str = LocalizationDatabase.GetLocalizedStringWithGroupName(str, groupName);
return new_str;
}
[ExcludeFromDocs]
public static string TrPath(string path)
{
string[] separatingChars = { "/" };
var result = new System.Text.StringBuilder(256);
var items = path.Split(separatingChars, System.StringSplitOptions.RemoveEmptyEntries);
for (var i = 0; i < items.Length; ++i)
{
result.Append(Tr(items[i]));
if (i < items.Length - 1)
result.Append("/");
}
return result.ToString();
}
[ExcludeFromDocs]
public static GUIContent TextContent(string text, string tooltip = null, Texture icon = null)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TrTextContent(text, tooltip, icon);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_text = LocalizationDatabase.GetLocalizedStringWithGroupName(text, groupName);
var new_tooltip = LocalizationDatabase.GetLocalizedStringWithGroupName(tooltip, groupName);
var gc = new GUIContent(new_text);
gc.tooltip = new_tooltip;
gc.image = icon;
return gc;
}
else
{
return EditorGUIUtility.TrTextContent(text, tooltip, icon);
}
}
[ExcludeFromDocs]
public static GUIContent TextContent(string text, string tooltip, string iconName)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TrTextContent(text, tooltip, iconName);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_text = LocalizationDatabase.GetLocalizedStringWithGroupName(text, groupName);
var new_tooltip = LocalizationDatabase.GetLocalizedStringWithGroupName(tooltip, groupName);
var gc = new GUIContent(new_text);
gc.tooltip = new_tooltip;
gc.image = EditorGUIUtility.LoadIconRequired(iconName);
return gc;
}
else
{
return EditorGUIUtility.TrTextContent(text, tooltip, iconName);
}
}
[ExcludeFromDocs]
public static GUIContent TextContent(string text, Texture icon)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TrTextContentWithIcon(text, icon);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_text = LocalizationDatabase.GetLocalizedStringWithGroupName(text, groupName);
var gc = new GUIContent(new_text);
gc.image = icon;
return gc;
}
else
{
return EditorGUIUtility.TrTextContentWithIcon(text, icon);
}
}
[ExcludeFromDocs]
public static GUIContent TextContentWithIcon(string text, Texture icon)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TrTextContentWithIcon(text, icon);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_text = LocalizationDatabase.GetLocalizedStringWithGroupName(text, groupName);
var gc = new GUIContent(new_text);
gc.image = icon;
return gc;
}
else
{
return EditorGUIUtility.TrTextContentWithIcon(text, icon);
}
}
[ExcludeFromDocs]
public static GUIContent TextContentWithIcon(string text, string iconName)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TextContentWithIcon(text, iconName);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_text = LocalizationDatabase.GetLocalizedStringWithGroupName(text, groupName);
var gc = new GUIContent(new_text);
gc.image = EditorGUIUtility.LoadIconRequired(iconName);
return gc;
}
else
{
return EditorGUIUtility.TextContentWithIcon(text, iconName);
}
}
[ExcludeFromDocs]
public static GUIContent TextContentWithIcon(string text, string tooltip, string iconName)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TrTextContentWithIcon(text, tooltip, iconName);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_text = LocalizationDatabase.GetLocalizedStringWithGroupName(text, groupName);
var new_tooltip = LocalizationDatabase.GetLocalizedStringWithGroupName(tooltip, groupName);
var gc = new GUIContent(new_text);
gc.tooltip = new_tooltip;
gc.image = EditorGUIUtility.LoadIconRequired(iconName);
return gc;
}
else
{
return EditorGUIUtility.TrTextContentWithIcon(text, tooltip, iconName);
}
}
[ExcludeFromDocs]
public static GUIContent TextContentWithIcon(string text, string tooltip, Texture icon)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TrTextContentWithIcon(text, tooltip, icon);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_text = LocalizationDatabase.GetLocalizedStringWithGroupName(text, groupName);
var new_tooltip = LocalizationDatabase.GetLocalizedStringWithGroupName(tooltip, groupName);
var gc = new GUIContent(new_text);
gc.tooltip = new_tooltip;
gc.image = icon;
return gc;
}
else
{
return EditorGUIUtility.TrTextContentWithIcon(text, tooltip, icon);
}
}
[ExcludeFromDocs]
public static GUIContent TextContentWithIcon(string text, string tooltip, MessageType messageType)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TrTextContentWithIcon(text, tooltip, messageType);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_text = LocalizationDatabase.GetLocalizedStringWithGroupName(text, groupName);
var new_tooltip = LocalizationDatabase.GetLocalizedStringWithGroupName(tooltip, groupName);
var gc = new GUIContent(new_text);
gc.tooltip = new_tooltip;
gc.image = EditorGUIUtility.GetHelpIcon(messageType);
return gc;
}
else
{
return EditorGUIUtility.TrTextContentWithIcon(text, tooltip, messageType);
}
}
[ExcludeFromDocs]
public static GUIContent TextContentWithIcon(string text, MessageType messageType)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TrTextContentWithIcon(text, messageType);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_text = LocalizationDatabase.GetLocalizedStringWithGroupName(text, groupName);
var gc = new GUIContent(new_text);
gc.image = EditorGUIUtility.GetHelpIcon(messageType);
return gc;
}
else
{
return EditorGUIUtility.TrTextContentWithIcon(text, messageType);
}
}
[ExcludeFromDocs]
public static GUIContent IconContent(string iconName, string tooltip = null)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TrIconContent(iconName, tooltip);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_tooltip = LocalizationDatabase.GetLocalizedStringWithGroupName(tooltip, groupName);
var gc = new GUIContent();
gc.tooltip = new_tooltip;
gc.image = EditorGUIUtility.LoadIconRequired(iconName);
return gc;
}
else
{
return EditorGUIUtility.TrIconContent(iconName, tooltip);
}
}
[ExcludeFromDocs]
public static GUIContent IconContent(Texture icon, string tooltip = null)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TrIconContent(icon, tooltip);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_tooltip = LocalizationDatabase.GetLocalizedStringWithGroupName(tooltip, groupName);
var gc = new GUIContent();
gc.tooltip = new_tooltip;
gc.image = icon;
return gc;
}
else
{
return EditorGUIUtility.TrIconContent(icon, tooltip);
}
}
[ExcludeFromDocs]
public static GUIContent TempContent(string t)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TempContent(t);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
var new_t = LocalizationDatabase.GetLocalizedStringWithGroupName(t, groupName);
return EditorGUIUtility.TempContent(new_t);
}
else
{
return EditorGUIUtility.TempContent(t);
}
}
[ExcludeFromDocs]
public static GUIContent[] TempContent(string[] texts)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TempContent(texts);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
GUIContent[] retval = new GUIContent[texts.Length];
for (int i = 0; i < texts.Length; i++)
{
var new_t = LocalizationDatabase.GetLocalizedStringWithGroupName(texts[i], groupName);
retval[i] = new GUIContent(new_t);
}
return retval;
}
else
{
return EditorGUIUtility.TempContent(texts);
}
}
[ExcludeFromDocs]
public static GUIContent[] TempContent(string[] texts, string[] tooltips)
{
if (!LocalizationDatabase.enableEditorLocalization)
return EditorGUIUtility.TempContent(texts, tooltips);
var groupName = GetGroupName(Assembly.GetCallingAssembly());
if (groupName != null)
{
GUIContent[] retval = new GUIContent[texts.Length];
for (int i = 0; i < texts.Length; i++)
{
var new_t = LocalizationDatabase.GetLocalizedStringWithGroupName(texts[i], groupName);
var new_tooltip = LocalizationDatabase.GetLocalizedStringWithGroupName(tooltips[i], groupName);
retval[i] = new GUIContent(new_t, new_tooltip);
}
return retval;
}
else
{
return EditorGUIUtility.TempContent(texts);
}
}
}
internal static class LocalizationGroupStack
{
static Stack s_GroupNameStack;
public static void Push(string groupName)
{
if (s_GroupNameStack == null)
s_GroupNameStack = new Stack();
if (s_GroupNameStack.Count >= 16)
Assert.IsTrue(false); // check the leak.
s_GroupNameStack.Push(groupName);
LocalizationDatabase.SetContextGroupName(groupName);
}
public static void Pop()
{
if (s_GroupNameStack == null || s_GroupNameStack.Count <= 0)
Assert.IsTrue(false);
s_GroupNameStack.Pop();
if (s_GroupNameStack.Count > 0)
{
string top = s_GroupNameStack.Peek();
LocalizationDatabase.SetContextGroupName(top);
}
else
LocalizationDatabase.SetContextGroupName(null);
}
}
///
/// This provides an auto dispose Localization system.
/// This can be called recursively.
///
public class LocalizationGroup : IDisposable
{
string m_LocGroupName;
bool m_Pushed = false;
///
/// a current group name for the localization.
///
public string locGroupName { get { return m_LocGroupName; } }
///
/// Default constructor.
///
public LocalizationGroup()
{
initialize(Assembly.GetCallingAssembly());
}
///
/// constructor.
/// group name will become the name of Assembly the behaviour belongs to.
///
public LocalizationGroup(Behaviour behaviour)
{
if (behaviour != null)
{
System.Type type = behaviour.GetType();
initialize(type.Assembly);
}
}
///
/// constructor.
/// group name will become the name of Assembly the type belongs to.
///
public LocalizationGroup(System.Type type)
{
initialize(type.Assembly);
}
///
/// constructor.
/// group name will become the name of Assembly the obj belongs to.
///
public LocalizationGroup(System.Object obj)
{
if (obj == null)
return;
initialize(obj.GetType().Assembly);
}
void initialize(System.Reflection.Assembly assembly)
{
string groupName = L10n.GetGroupName(assembly);
LocalizationGroupStack.Push(groupName);
m_Pushed = true;
m_LocGroupName = groupName;
}
///
/// dispose current state.
///
public void Dispose()
{
if (m_Pushed)
LocalizationGroupStack.Pop();
}
}
}
namespace UnityEditor.Localization.Editor
{
///
/// This provides Localization function for Packages.
///
[System.Obsolete("Localization has been deprecated. Please use UnityEditor.L10n instead", true)]
public static class Localization
{
///
/// get proper translation for the given argument.
///
[System.Obsolete("Obsolete msg (UnityUpgradable) -> UnityEditor.L10n.Tr(*)", true)]
public static string Tr(string str)
{
if (!LocalizationDatabase.enableEditorLocalization)
return str;
var assembly = Assembly.GetCallingAssembly();
object[] attrobjs = assembly.GetCustomAttributes(typeof(LocalizationAttribute), true /* inherit */);
if (attrobjs != null && attrobjs.Length > 0 && attrobjs[0] != null)
{
LocalizationAttribute locAttr = (LocalizationAttribute)attrobjs[0];
string locGroupName = locAttr.locGroupName;
if (locGroupName == null)
locGroupName = assembly.GetName().Name;
var new_str = LocalizationDatabase.GetLocalizedStringWithGroupName(str, locGroupName);
return new_str;
}
return str;
}
}
///
/// This provides an auto dispose Localization system.
/// This can be called recursively.
///
[System.Obsolete("LocalizationGroup has been deprecated. Please use UnityEditor.LocalizationGroup instead", true)]
public class LocalizationGroup : IDisposable
{
string m_LocGroupName;
bool m_Pushed = false;
///
/// a current group name for the localization.
///
public string locGroupName { get { return m_LocGroupName; } }
///
/// Default constructor.
///
public LocalizationGroup()
{
initialize(Assembly.GetCallingAssembly());
}
///
/// constructor.
/// group name will become the name of Assembly the behaviour belongs to.
///
public LocalizationGroup(Behaviour behaviour)
{
if (behaviour != null)
{
System.Type type = behaviour.GetType();
initialize(type.Assembly);
}
}
///
/// constructor.
/// group name will become the name of Assembly the type belongs to.
///
public LocalizationGroup(System.Type type)
{
initialize(type.Assembly);
}
///
/// constructor.
/// group name will become the name of Assembly the obj belongs to.
///
public LocalizationGroup(System.Object obj)
{
if (obj == null)
return;
initialize(obj.GetType().Assembly);
}
void initialize(System.Reflection.Assembly assembly)
{
string groupName = null;
object[] attrobjs = assembly.GetCustomAttributes(typeof(LocalizationAttribute), true /* inherit */);
if (attrobjs != null && attrobjs.Length > 0 && attrobjs[0] != null) // focus on only the first.
{
LocalizationAttribute locAttr = (LocalizationAttribute)attrobjs[0];
groupName = locAttr.locGroupName;
if (groupName == null)
groupName = assembly.GetName().Name;
}
LocalizationGroupStack.Push(groupName);
m_Pushed = true;
m_LocGroupName = groupName;
}
///
/// dispose current state.
///
public void Dispose()
{
if (m_Pushed)
LocalizationGroupStack.Pop();
}
}
}