mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-07 16:45:10 +00:00
LanguageModule And Procedure InitLanguage
This commit is contained in:
8
UnityProject/Assets/Editor.meta
Normal file
8
UnityProject/Assets/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b35096feecdb5a4d894aa81a28f72e5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
UnityProject/Assets/Editor/I2Localization.meta
Normal file
8
UnityProject/Assets/Editor/I2Localization.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f183cc1bcf4014f4c80a8580caabcd3f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
40
UnityProject/Assets/Editor/I2Localization/I2Languages.asset
Normal file
40
UnityProject/Assets/Editor/I2Localization/I2Languages.asset
Normal file
@@ -0,0 +1,40 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2f0b0c553be8edd4682e9180fdd13e37, type: 3}
|
||||
m_Name: I2Languages
|
||||
m_EditorClassIdentifier:
|
||||
mSource:
|
||||
UserAgreesToHaveItOnTheScene: 0
|
||||
UserAgreesToHaveItInsideThePluginsFolder: 0
|
||||
GoogleLiveSyncIsUptoDate: 1
|
||||
mTerms: []
|
||||
CaseInsensitiveTerms: 0
|
||||
OnMissingTranslation: 1
|
||||
mTerm_AppName:
|
||||
mLanguages: []
|
||||
IgnoreDeviceLanguage: 0
|
||||
_AllowUnloadingLanguages: 0
|
||||
Google_WebServiceURL:
|
||||
Google_SpreadsheetKey:
|
||||
Google_SpreadsheetName:
|
||||
Google_LastUpdatedVersion:
|
||||
Google_Password: change_this
|
||||
GoogleUpdateFrequency: 3
|
||||
GoogleInEditorCheckFrequency: 2
|
||||
GoogleUpdateSynchronization: 1
|
||||
GoogleUpdateDelay: 0
|
||||
Assets: []
|
||||
Spreadsheet_LocalFileName:
|
||||
Spreadsheet_LocalCSVSeparator: ','
|
||||
Spreadsheet_LocalCSVEncoding: utf-8
|
||||
Spreadsheet_SpecializationAsRows: 1
|
||||
Spreadsheet_SortRows: 1
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50fd67a84c64e184c85bf3e1e343ba87
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -11,6 +11,14 @@ namespace Procedure
|
||||
public class ProcedureLaunch : ProcedureBase
|
||||
{
|
||||
public override bool UseNativeDialog => true;
|
||||
|
||||
private IAudioModule _audioModule;
|
||||
|
||||
protected override void OnInit(ProcedureOwner procedureOwner)
|
||||
{
|
||||
_audioModule = ModuleSystem.GetModule<IAudioModule>();
|
||||
base.OnInit(procedureOwner);
|
||||
}
|
||||
|
||||
protected override void OnEnter(ProcedureOwner procedureOwner)
|
||||
{
|
||||
@@ -36,49 +44,49 @@ namespace Procedure
|
||||
|
||||
private void InitLanguageSettings()
|
||||
{
|
||||
// if (GameModule.Resource.PlayMode == EPlayMode.EditorSimulateMode && GameModule.Base.EditorLanguage == Language.Unspecified)
|
||||
// {
|
||||
// // 编辑器资源模式直接使用 Inspector 上设置的语言
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// Language language = GameModule.Localization.Language;
|
||||
// if (GameModule.Setting.HasSetting(Constant.Setting.Language))
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// string languageString = GameModule.Setting.GetString(Constant.Setting.Language);
|
||||
// language = (Language)System.Enum.Parse(typeof(Language), languageString);
|
||||
// }
|
||||
// catch(System.Exception exception)
|
||||
// {
|
||||
// Log.Error("Init language error, reason {0}",exception.ToString());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (language != Language.English
|
||||
// && language != Language.ChineseSimplified
|
||||
// && language != Language.ChineseTraditional)
|
||||
// {
|
||||
// // 若是暂不支持的语言,则使用英语
|
||||
// language = Language.English;
|
||||
//
|
||||
// GameModule.Setting.SetString(Constant.Setting.Language, language.ToString());
|
||||
// GameModule.Setting.Save();
|
||||
// }
|
||||
//
|
||||
// GameModule.Localization.Language = language;
|
||||
// Log.Info("Init language settings complete, current language is '{0}'.", language.ToString());
|
||||
if (_resourceModule.PlayMode == EPlayMode.EditorSimulateMode && RootModule.Instance.EditorLanguage == Language.Unspecified)
|
||||
{
|
||||
// 编辑器资源模式直接使用 Inspector 上设置的语言
|
||||
return;
|
||||
}
|
||||
|
||||
Language language = LocalizationModule.Instance.Language;
|
||||
if (Utility.PlayerPrefs.HasSetting(Constant.Setting.Language))
|
||||
{
|
||||
try
|
||||
{
|
||||
string languageString = Utility.PlayerPrefs.GetString(Constant.Setting.Language);
|
||||
language = (Language)System.Enum.Parse(typeof(Language), languageString);
|
||||
}
|
||||
catch(System.Exception exception)
|
||||
{
|
||||
Log.Error("Init language error, reason {0}",exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (language != Language.English
|
||||
&& language != Language.ChineseSimplified
|
||||
&& language != Language.ChineseTraditional)
|
||||
{
|
||||
// 若是暂不支持的语言,则使用英语
|
||||
language = Language.English;
|
||||
|
||||
Utility.PlayerPrefs.SetString(Constant.Setting.Language, language.ToString());
|
||||
Utility.PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
LocalizationModule.Instance.Language = language;
|
||||
Log.Info("Init language settings complete, current language is '{0}'.", language.ToString());
|
||||
}
|
||||
|
||||
private void InitSoundSettings()
|
||||
{
|
||||
// GameModule.Audio.MusicEnable = !GameModule.Setting.GetBool(Constant.Setting.MusicMuted, false);
|
||||
// GameModule.Audio.MusicVolume = GameModule.Setting.GetFloat(Constant.Setting.MusicVolume, 1f);
|
||||
// GameModule.Audio.SoundEnable = !GameModule.Setting.GetBool(Constant.Setting.SoundMuted, false);
|
||||
// GameModule.Audio.SoundVolume = GameModule.Setting.GetFloat(Constant.Setting.SoundVolume, 1f);
|
||||
// GameModule.Audio.UISoundEnable = !GameModule.Setting.GetBool(Constant.Setting.UISoundMuted, false);
|
||||
// GameModule.Audio.UISoundVolume = GameModule.Setting.GetFloat(Constant.Setting.UISoundVolume, 1f);
|
||||
_audioModule.MusicEnable = !Utility.PlayerPrefs.GetBool(Constant.Setting.MusicMuted, false);
|
||||
_audioModule.MusicVolume = Utility.PlayerPrefs.GetFloat(Constant.Setting.MusicVolume, 1f);
|
||||
_audioModule.SoundEnable = !Utility.PlayerPrefs.GetBool(Constant.Setting.SoundMuted, false);
|
||||
_audioModule.SoundVolume = Utility.PlayerPrefs.GetFloat(Constant.Setting.SoundVolume, 1f);
|
||||
_audioModule.UISoundEnable = !Utility.PlayerPrefs.GetBool(Constant.Setting.UISoundMuted, false);
|
||||
_audioModule.UISoundVolume = Utility.PlayerPrefs.GetFloat(Constant.Setting.UISoundVolume, 1f);
|
||||
Log.Info("Init sound settings complete.");
|
||||
}
|
||||
}
|
||||
|
8
UnityProject/Assets/TEngine/Editor/Localization.meta
Normal file
8
UnityProject/Assets/TEngine/Editor/Localization.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eee776b99f3e76a4c968d6943979829b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
763
UnityProject/Assets/TEngine/Editor/Localization/EditorTools.cs
Normal file
763
UnityProject/Assets/TEngine/Editor/Localization/EditorTools.cs
Normal file
@@ -0,0 +1,763 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public class GUITools
|
||||
{
|
||||
static public Color White = Color.white;
|
||||
static public Color LightGray = Color.Lerp(Color.gray, Color.white, 0.5f);
|
||||
static public Color DarkGray = Color.Lerp(Color.gray, Color.white, 0.2f);
|
||||
static public Color LightYellow = Color.Lerp(Color.yellow, Color.white, 0.5f);
|
||||
|
||||
static public GUILayoutOption DontExpandWidth = GUILayout.ExpandWidth(false);
|
||||
static public GUIContent EmptyContent = new GUIContent ();
|
||||
|
||||
static List<System.Action> mDelayedEditorCallbacks = new List<System.Action>();
|
||||
|
||||
#region Delayed Editor Callback
|
||||
|
||||
public static void DelayedCall( System.Action action )
|
||||
{
|
||||
if (mDelayedEditorCallbacks.Count == 0)
|
||||
EditorApplication.update += OnDelayedCall;
|
||||
|
||||
mDelayedEditorCallbacks.Add(action);
|
||||
}
|
||||
|
||||
static void OnDelayedCall()
|
||||
{
|
||||
EditorApplication.update -= OnDelayedCall;
|
||||
var calls = mDelayedEditorCallbacks.ToArray();
|
||||
mDelayedEditorCallbacks.Clear();
|
||||
|
||||
foreach (var call in calls)
|
||||
call();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Header
|
||||
public delegate void fnOnToggled(bool enabled);
|
||||
static public bool DrawHeader (string text, string key, bool ShowToggle=false, bool ToggleState=false, fnOnToggled OnToggle = null, string HelpURL=default(string), Color disabledColor = default(Color))
|
||||
{
|
||||
bool state = EditorPrefs.GetBool(key, false);
|
||||
|
||||
bool newState = DrawHeader (text, state, ShowToggle, ToggleState, OnToggle, HelpURL, disabledColor);
|
||||
|
||||
if (state!=newState) EditorPrefs.SetBool(key, newState);
|
||||
return newState;
|
||||
}
|
||||
|
||||
static public bool DrawHeader (string text, bool state, bool ShowToggle=false, bool ToggleState=false, fnOnToggled OnToggle = null, string HelpURL=default(string), Color disabledColor = default(Color), bool allowCollapsing = true)
|
||||
{
|
||||
GUIStyle Style = new GUIStyle(EditorStyles.foldout);
|
||||
Style.richText = true;
|
||||
EditorStyles.foldout.richText = true;
|
||||
if (state)
|
||||
{
|
||||
//GUI.backgroundColor=DarkGray;
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea/*, GUILayout.Height(1)*/);
|
||||
GUILayout.BeginHorizontal();
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
if (allowCollapsing)
|
||||
state = GUILayout.Toggle(state, text, Style, GUILayout.ExpandWidth(true));
|
||||
else
|
||||
GUILayout.Label(text, GUILayout.ExpandWidth(true));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(HelpURL))
|
||||
{
|
||||
if (GUILayout.Button (Icon_Help, EditorStyles.label, GUILayout.ExpandWidth(false)))
|
||||
Application.OpenURL(HelpURL);
|
||||
}
|
||||
if (ShowToggle)
|
||||
{
|
||||
GUI.changed = false;
|
||||
bool newBool = GUILayout.Toggle(ToggleState, "", "OL Toggle", GUILayout.ExpandWidth(false));
|
||||
if (GUI.changed && OnToggle!=null)
|
||||
OnToggle(newBool);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(2);
|
||||
|
||||
//GUI.backgroundColor = Color.white;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ShowToggle && !ToggleState)
|
||||
GUI.color = disabledColor;
|
||||
|
||||
GUILayout.BeginHorizontal("Box");
|
||||
//GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
state = GUILayout.Toggle(state, text, Style, GUILayout.ExpandWidth(true));
|
||||
if (ShowToggle)
|
||||
{
|
||||
GUI.changed = false;
|
||||
bool newBool = GUILayout.Toggle(ToggleState, "", "OL Toggle", GUILayout.ExpandWidth(false));
|
||||
if (GUI.changed && OnToggle!=null)
|
||||
OnToggle(newBool);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
GUI.color = White;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
static public void CloseHeader()
|
||||
{
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public static void OnGUI_Footer(string pluginName, string pluginVersion, string helpURL, string documentationURL, string assetStoreURL)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
string versionTip = "";
|
||||
/*if (I2Analytics.HasNewVersion(pluginName))
|
||||
{
|
||||
versionTip = "There is a new version of " + pluginName + ".\nClick here for more details";
|
||||
if (GUILayout.Button(new GUIContent("", versionTip), EditorStyles.label, GUILayout.Width(25)))
|
||||
I2AboutWindow.DoShowScreen();
|
||||
|
||||
var rect = GUILayoutUtility.GetLastRect();
|
||||
rect.yMin = rect.yMax - 25;
|
||||
rect.xMax = rect.xMin + 25;
|
||||
rect.y += 3;
|
||||
GUITools.DrawSkinIcon(rect, "CN EntryWarnIcon", "CN EntryWarn");
|
||||
}*/
|
||||
|
||||
if (GUILayout.Button(new GUIContent("v" + pluginVersion, versionTip), EditorStyles.miniLabel))
|
||||
{
|
||||
Application.OpenURL(assetStoreURL);
|
||||
//I2AboutWindow.DoShowScreen();
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button("Ask a Question", EditorStyles.miniLabel))
|
||||
Application.OpenURL(helpURL);
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
if (GUILayout.Button("Documentation", EditorStyles.miniLabel))
|
||||
Application.OpenURL(documentationURL);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Content
|
||||
|
||||
static public void BeginContents ()
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.MinHeight(10f));
|
||||
GUILayout.Space(2f);
|
||||
EditorGUILayout.BeginVertical();
|
||||
GUILayout.Space(2f);
|
||||
}
|
||||
|
||||
static public void EndContents () { EndContents(true); }
|
||||
static public void EndContents ( bool closeHeader )
|
||||
{
|
||||
GUILayout.Space(2f);
|
||||
EditorGUILayout.EndVertical();
|
||||
GUILayout.Space(3f);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (closeHeader) CloseHeader();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tabs
|
||||
|
||||
static public void DrawTabs( SerializedProperty mProperty, GUIStyle Style=null, int height=25 )
|
||||
{
|
||||
int curIndex = mProperty.enumValueIndex;
|
||||
int newIndex = DrawTabs( curIndex, mProperty.enumNames, Style, height);
|
||||
|
||||
if (curIndex!=newIndex)
|
||||
mProperty.enumValueIndex = newIndex;
|
||||
}
|
||||
|
||||
static public int DrawTabs( int Index, string[] Tabs, GUIStyle Style=null, int height=25, bool expand = true)
|
||||
{
|
||||
GUIStyle MyStyle = new GUIStyle(Style!=null?Style:GUI.skin.FindStyle("dragtab"));
|
||||
MyStyle.fixedHeight=0;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
for (int i=0; i<Tabs.Length; ++i)
|
||||
{
|
||||
int idx = Tabs[i].IndexOf('|');
|
||||
if (idx>0)
|
||||
{
|
||||
string text = Tabs[i].Substring(0, idx);
|
||||
string tooltip = Tabs[i].Substring(idx+1);
|
||||
if ( GUILayout.Toggle(Index==i, new GUIContent(text, tooltip), MyStyle, GUILayout.Height(height), GUILayout.ExpandWidth(expand)) && Index!=i)
|
||||
{
|
||||
Index=i;
|
||||
GUI.FocusControl(string.Empty);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( GUILayout.Toggle(Index==i, Tabs[i], MyStyle, GUILayout.Height(height), GUILayout.ExpandWidth(expand)) && Index!=i)
|
||||
{
|
||||
Index=i;
|
||||
GUI.FocusControl(string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
return Index;
|
||||
}
|
||||
|
||||
static public void DrawShadowedTabs( SerializedProperty mProperty, GUIStyle Style=null, int height=25, bool expand=true )
|
||||
{
|
||||
int curIndex = mProperty.enumValueIndex;
|
||||
int newIndex = DrawShadowedTabs( curIndex, mProperty.enumNames, height, expand);
|
||||
|
||||
if (curIndex!=newIndex)
|
||||
mProperty.enumValueIndex = newIndex;
|
||||
}
|
||||
|
||||
static public int DrawShadowedTabs( int Index, string[] Tabs, int height = 25, bool expand=true )
|
||||
{
|
||||
GUI.backgroundColor=Color.Lerp (Color.gray, Color.white, 0.2f);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
GUI.backgroundColor=Color.white;
|
||||
GUILayout.Space(2);
|
||||
Index = DrawTabs( Index, Tabs, height: height, expand:expand );
|
||||
GUILayout.EndVertical();
|
||||
return Index;
|
||||
}
|
||||
|
||||
static public int DrawTabs( int Index, Texture2D[] Tabs, GUIStyle Style, int height )
|
||||
{
|
||||
GUIStyle MyStyle = new GUIStyle(Style!=null?Style:GUI.skin.FindStyle("dragtab"));
|
||||
MyStyle.fixedHeight=0;
|
||||
|
||||
//width = Mathf.Max (width, height * Tabs[0].width/(float)Tabs[0].height);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
float width = (EditorGUIUtility.currentViewWidth-(MyStyle.border.left+MyStyle.border.right)*(Tabs.Length-1)) / Tabs.Length;
|
||||
for (int i=0; i<Tabs.Length; ++i)
|
||||
{
|
||||
if ( GUILayout.Toggle(Index==i, Tabs[i], MyStyle, GUILayout.Height(height), GUILayout.Width(width)) && Index!=i)
|
||||
{
|
||||
Index=i;
|
||||
GUI.changed = true;
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
return Index;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Object Array
|
||||
|
||||
static public bool DrawObjectsArray( SerializedProperty PropArray, bool allowDuplicates=false, bool allowResources=false, bool allowSceneObj=false, Object testAdd=null, Object testReplace=null, int testReplaceIndex=-1, int testDeleteIndex=-1 )
|
||||
{
|
||||
bool hasChanged = false;
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
int DeleteElement = -1, MoveUpElement = -1;
|
||||
|
||||
for (int i=0, imax=PropArray.arraySize; i<imax; ++i)
|
||||
{
|
||||
SerializedProperty Prop = PropArray.GetArrayElementAtIndex(i);
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
//--[ Delete Button ]-------------------
|
||||
if (GUILayout.Button("X", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)) || i == testDeleteIndex)
|
||||
DeleteElement = i;
|
||||
|
||||
GUILayout.Space(2);
|
||||
//--[ Object ]--------------------------
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
GUI.changed = false;
|
||||
Object Obj = EditorGUILayout.ObjectField( Prop.objectReferenceValue, typeof(Object), allowSceneObj, GUILayout.ExpandWidth(true));
|
||||
if (testReplaceIndex == i)
|
||||
{
|
||||
Obj = testReplace;
|
||||
GUI.changed = true;
|
||||
}
|
||||
|
||||
if (!allowResources && Obj != null)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(Obj);
|
||||
if (path != null && path.Contains("/Resources/"))
|
||||
Obj = null;
|
||||
}
|
||||
|
||||
if (Obj==null)
|
||||
DeleteElement = i;
|
||||
else
|
||||
if (GUI.changed && (allowDuplicates || !ObjectsArrayHasReference(PropArray, Obj)))
|
||||
{
|
||||
Prop.objectReferenceValue = Obj;
|
||||
hasChanged = true;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
//--[ MoveUp Button ]-------------------
|
||||
if (i==0)
|
||||
{
|
||||
if (imax>1)
|
||||
GUILayout.Space (18);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUILayout.Button( "\u25B2", EditorStyles.toolbarButton, GUILayout.Width(18)))
|
||||
MoveUpElement = i;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
Object NewObj = EditorGUILayout.ObjectField( null, typeof(Object), allowSceneObj, GUILayout.ExpandWidth(true));
|
||||
if (testAdd != null)
|
||||
{
|
||||
NewObj = testAdd;
|
||||
}
|
||||
|
||||
if (!allowResources && NewObj != null)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(NewObj);
|
||||
if (path != null && path.Contains("/Resources/"))
|
||||
NewObj = null;
|
||||
}
|
||||
if (NewObj && (allowDuplicates || !ObjectsArrayHasReference(PropArray, NewObj)))
|
||||
{
|
||||
int Index = PropArray.arraySize;
|
||||
PropArray.InsertArrayElementAtIndex( Index );
|
||||
PropArray.GetArrayElementAtIndex(Index).objectReferenceValue = NewObj;
|
||||
hasChanged = true;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (DeleteElement>=0)
|
||||
{
|
||||
PropArray.DeleteArrayElementAtIndex( DeleteElement );
|
||||
//PropArray.DeleteArrayElementAtIndex( DeleteElement );
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
if (MoveUpElement>=0)
|
||||
{
|
||||
PropArray.MoveArrayElement(MoveUpElement, MoveUpElement-1);
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
return hasChanged;
|
||||
}
|
||||
|
||||
static public bool ObjectsArrayHasReference(SerializedProperty PropArray, Object obj)
|
||||
{
|
||||
for (int i = 0, imax = PropArray.arraySize; i < imax; ++i)
|
||||
{
|
||||
SerializedProperty Prop = PropArray.GetArrayElementAtIndex(i);
|
||||
if (Prop.objectReferenceValue == obj)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Toggle
|
||||
|
||||
static public int ToggleToolbar( int Index, string[] Options )
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
for (int i=0; i<Options.Length; ++i)
|
||||
{
|
||||
if ( GUILayout.Toggle(Index==i, Options[i], EditorStyles.toolbarButton))
|
||||
Index=i;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
return Index;
|
||||
}
|
||||
|
||||
static public void ToggleToolbar( SerializedProperty EnumVar )
|
||||
{
|
||||
int index = ToggleToolbar( EnumVar.enumValueIndex, EnumVar.enumNames);
|
||||
if (EnumVar.enumValueIndex != index)
|
||||
EnumVar.enumValueIndex = index;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Misc
|
||||
|
||||
public static bool ObjectExistInScene( GameObject Obj )
|
||||
{
|
||||
return Obj.scene.IsValid() && Obj.scene.isLoaded;
|
||||
/* //if (Obj.transform.root != Obj.transform)
|
||||
// continue;
|
||||
|
||||
// We are only interested in GameObjects that are visible in the Hierachy panel and are persitent
|
||||
if ((Obj.hideFlags & (HideFlags.DontSave|HideFlags.HideInHierarchy)) > 0)
|
||||
return false;
|
||||
|
||||
// We are not interested in Prefab, unless they are Prefab Instances
|
||||
PrefabType pfType = PrefabUtility.GetPrefabType(Obj);
|
||||
if(pfType == PrefabType.Prefab || pfType == PrefabType.ModelPrefab)
|
||||
return false;
|
||||
|
||||
// If the database contains the object then its not an scene object,
|
||||
// but the previous test should get rid of them, so I will just comment this
|
||||
// unless an false positive object is found in the future
|
||||
//if (AssetDatabase.Contains(Obj))
|
||||
// return false;
|
||||
|
||||
return true;*/
|
||||
}
|
||||
|
||||
public static IEnumerable<GameObject> SceneRoots()
|
||||
{
|
||||
var prop = new HierarchyProperty(HierarchyType.GameObjects);
|
||||
var expanded = new int[0];
|
||||
while (prop.Next(expanded)) {
|
||||
yield return prop.pptrValue as GameObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<GameObject> SceneRootsList()
|
||||
{
|
||||
return new List<GameObject>(SceneRoots());
|
||||
}
|
||||
|
||||
public static IEnumerable<Transform> AllSceneObjects()
|
||||
{
|
||||
var queue = new Queue<Transform>();
|
||||
|
||||
foreach (var root in SceneRoots()) {
|
||||
var tf = root.transform;
|
||||
yield return tf;
|
||||
queue.Enqueue(tf);
|
||||
}
|
||||
|
||||
while (queue.Count > 0) {
|
||||
foreach (Transform child in queue.Dequeue()) {
|
||||
yield return child;
|
||||
queue.Enqueue(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetScenePath(Transform tr)
|
||||
{
|
||||
if (tr==null)
|
||||
return string.Empty;
|
||||
|
||||
string path = tr.name;
|
||||
while (tr.parent != null)
|
||||
{
|
||||
tr = tr.parent;
|
||||
path = tr.name + "/" + path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
public static Transform FindObjectInEditor( string scenePath )
|
||||
{
|
||||
if (string.IsNullOrEmpty(scenePath))
|
||||
return null;
|
||||
|
||||
int index = scenePath.IndexOfAny("/\\".ToCharArray());
|
||||
string first = index<0 ? scenePath : scenePath.Substring(0, index);
|
||||
|
||||
foreach (var root in AllSceneObjects())
|
||||
if (root.name==first)
|
||||
{
|
||||
if (index<0)
|
||||
return root;
|
||||
|
||||
return root.Find(scenePath.Substring(index+1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static GUIContent Icon_Help {
|
||||
get{
|
||||
if (mIconHelp == null)
|
||||
mIconHelp = EditorGUIUtility.IconContent("_Help");
|
||||
return mIconHelp;
|
||||
}
|
||||
}
|
||||
static GUIContent mIconHelp;
|
||||
|
||||
public static GUIStyle FindSkinStyle(string name)
|
||||
{
|
||||
var allStyles = GUI.skin.customStyles;
|
||||
for (int i = 0, imax = allStyles.Length; i < imax; ++i)
|
||||
{
|
||||
if (allStyles[i].name == name)
|
||||
return allStyles[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static void DrawSkinIcon(Rect rect, params string[] iconNames)
|
||||
{
|
||||
foreach (var icon in iconNames)
|
||||
{
|
||||
var style = FindSkinStyle(icon);
|
||||
if (style == null || style.normal == null || style.normal.background == null)
|
||||
continue;
|
||||
|
||||
GUI.DrawTexture(rect, style.normal.background);
|
||||
return;
|
||||
}
|
||||
//Debug.Log("unable to find icon");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Angle Drawer
|
||||
private static Vector2 mAngle_lastMousePosition;
|
||||
static Texture mAngle_TextureCircle;
|
||||
static Texture pAngle_TextureCircle {
|
||||
get{
|
||||
if (mAngle_TextureCircle) return mAngle_TextureCircle;
|
||||
mAngle_TextureCircle = GUI.skin.GetStyle("CN CountBadge").normal.background;
|
||||
return mAngle_TextureCircle;
|
||||
}
|
||||
}
|
||||
|
||||
public static float FloatAngle(Rect rect, float value)
|
||||
{
|
||||
return FloatAngle(rect, value, -1, -1, -1);
|
||||
}
|
||||
|
||||
public static float FloatAngle(Rect rect, float value, float snap)
|
||||
{
|
||||
return FloatAngle(rect, value, snap, -1, -1);
|
||||
}
|
||||
|
||||
public static float FloatAngle(Rect rect, float value, float snap, float min, float max)
|
||||
{
|
||||
int id = GUIUtility.GetControlID(FocusType.Passive, rect);
|
||||
|
||||
Rect knobRect = new Rect(rect.x, rect.y, rect.height, rect.height);
|
||||
|
||||
float delta;
|
||||
if (min != max)
|
||||
delta = (max - min) / 360;
|
||||
else
|
||||
delta = 1;
|
||||
|
||||
if (UnityEngine.Event.current != null)
|
||||
{
|
||||
if (UnityEngine.Event.current.type == EventType.MouseDown && knobRect.Contains(UnityEngine.Event.current.mousePosition))
|
||||
{
|
||||
GUIUtility.hotControl = id;
|
||||
mAngle_lastMousePosition = UnityEngine.Event.current.mousePosition;
|
||||
}
|
||||
else if (UnityEngine.Event.current.type == EventType.MouseUp && GUIUtility.hotControl == id)
|
||||
GUIUtility.hotControl = -1;
|
||||
else if (UnityEngine.Event.current.type == EventType.MouseDrag && GUIUtility.hotControl == id)
|
||||
{
|
||||
Vector2 move = mAngle_lastMousePosition - UnityEngine.Event.current.mousePosition;
|
||||
value += delta * (-move.x - move.y);
|
||||
|
||||
if (snap > 0)
|
||||
{
|
||||
float mod = value % snap;
|
||||
|
||||
if (mod < delta * 3 || Mathf.Abs(mod - snap) < delta * 3)
|
||||
value = Mathf.Round(value / snap) * snap;
|
||||
}
|
||||
|
||||
mAngle_lastMousePosition = UnityEngine.Event.current.mousePosition;
|
||||
GUI.changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pAngle_TextureCircle) GUI.DrawTexture(knobRect, pAngle_TextureCircle);
|
||||
Matrix4x4 matrix = GUI.matrix;
|
||||
|
||||
if (min != max)
|
||||
GUIUtility.RotateAroundPivot(value * (360 / (max - min)), knobRect.center);
|
||||
else
|
||||
GUIUtility.RotateAroundPivot(value, knobRect.center);
|
||||
|
||||
knobRect.height = 5;
|
||||
knobRect.width = 5;
|
||||
if (pAngle_TextureCircle) GUI.DrawTexture(knobRect, pAngle_TextureCircle);
|
||||
GUI.matrix = matrix;
|
||||
|
||||
Rect label = new Rect(rect.x + rect.height, rect.y + rect.height / 2 - 9, rect.height, 18);
|
||||
value = EditorGUI.FloatField(label, value);
|
||||
|
||||
if (min != max)
|
||||
value = Mathf.Clamp(value, min, max);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float AngleCircle(Rect rect, float angle, float snap, float min, float max, Texture background=null, Texture knobLine=null)
|
||||
{
|
||||
Rect knobRect = new Rect(rect.x, rect.y, rect.height, rect.height);
|
||||
|
||||
float delta;
|
||||
if (min != max)
|
||||
delta = (max - min) / 360;
|
||||
else
|
||||
delta = 1;
|
||||
|
||||
if (UnityEngine.Event.current != null && GUIUtility.hotControl<=0 && (UnityEngine.Event.current.type==EventType.MouseDown || UnityEngine.Event.current.type==EventType.MouseDrag) && knobRect.Contains(UnityEngine.Event.current.mousePosition))
|
||||
{
|
||||
angle = Vector2.Angle( Vector2.right, UnityEngine.Event.current.mousePosition-knobRect.center);
|
||||
if (UnityEngine.Event.current.mousePosition.y<knobRect.center.y) angle = 360-angle;
|
||||
if (UnityEngine.Event.current.alt || UnityEngine.Event.current.control)
|
||||
snap = 5;
|
||||
if (snap > 0)
|
||||
{
|
||||
float mod = Mathf.Repeat(angle, snap);
|
||||
|
||||
if (mod < delta * 3 || Mathf.Abs(mod - snap) < delta * 3)
|
||||
angle = Mathf.Round(angle / snap) * snap;
|
||||
}
|
||||
|
||||
GUI.changed = true;
|
||||
}
|
||||
|
||||
if (background==null) background = pAngle_TextureCircle;
|
||||
if (background) GUI.DrawTexture (knobRect, background);
|
||||
|
||||
Matrix4x4 matrix = GUI.matrix;
|
||||
|
||||
if (min != max)
|
||||
GUIUtility.RotateAroundPivot(angle * (360 / (max - min))+90, knobRect.center);
|
||||
else
|
||||
GUIUtility.RotateAroundPivot(angle+90, knobRect.center);
|
||||
|
||||
float Radius = Mathf.Min (knobRect.width, knobRect.height) * 0.5f;
|
||||
knobRect.x = knobRect.x + 0.5f * knobRect.width - 4;
|
||||
knobRect.y += 2;
|
||||
knobRect.width = 8;
|
||||
knobRect.height = Radius+2;
|
||||
if (knobLine == null)
|
||||
knobLine = GUI.skin.FindStyle ("MeBlendPosition").normal.background;
|
||||
if (knobLine) GUI.DrawTexture(knobRect, knobLine);
|
||||
GUI.matrix = matrix;
|
||||
|
||||
return Mathf.Repeat(angle, 360);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Unity Version branching
|
||||
|
||||
public static string Editor_GetCurrentScene()
|
||||
{
|
||||
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
|
||||
return EditorApplication.currentScene;
|
||||
#else
|
||||
return SceneManager.GetActiveScene().path;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Editor_MarkSceneDirty()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
|
||||
#else
|
||||
EditorApplication.MarkSceneDirty();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Editor_SaveScene()
|
||||
{
|
||||
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
|
||||
EditorApplication.SaveScene ();
|
||||
#else
|
||||
EditorSceneManager.SaveOpenScenes();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Editor_OpenScene( string sceneName )
|
||||
{
|
||||
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
|
||||
EditorApplication.OpenScene( sceneName );
|
||||
#else
|
||||
EditorSceneManager.OpenScene(sceneName);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Reflection
|
||||
static public object Reflection_InvokeMethod ( object instanceObject, string methodName, params object[] p_args )
|
||||
{
|
||||
BindingFlags _flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
|
||||
MethodInfo mi = instanceObject.GetType().GetMethods( _flags ).Where( x => x.Name==methodName ).FirstOrDefault();
|
||||
if (mi == null) return null;
|
||||
return mi.Invoke( instanceObject, p_args );
|
||||
}
|
||||
static public object Reflection_InvokeMethod ( Type targetType, string methodName, params object[] p_args )
|
||||
{
|
||||
BindingFlags _flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
|
||||
MethodInfo mi = targetType.GetMethods( _flags ).Where( x => x.Name==methodName ).FirstOrDefault();
|
||||
if (mi == null) return null;
|
||||
return mi.Invoke( null, p_args );
|
||||
}
|
||||
|
||||
|
||||
public static object s_RecycledEditor;
|
||||
public static string TextField ( Rect position, string text, int maxLength, GUIStyle style, int controlID )
|
||||
{
|
||||
if (s_RecycledEditor==null)
|
||||
{
|
||||
FieldInfo info = typeof(EditorGUI).GetField("s_RecycledEditor", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
s_RecycledEditor = info.GetValue(null);
|
||||
}
|
||||
|
||||
if (s_RecycledEditor == null)
|
||||
return "";
|
||||
|
||||
return Reflection_InvokeMethod( typeof( EditorGUI ), "DoTextField", s_RecycledEditor, controlID, position, text, style, null, false, false, false, false ) as string;
|
||||
}
|
||||
|
||||
static public void RepaintInspectors()
|
||||
{
|
||||
EditorApplication.update -= RepaintInspectors;
|
||||
var assemblyEditor = Assembly.GetAssembly(typeof(UnityEditor.Editor));
|
||||
var typeInspectorWindow = assemblyEditor.GetType("UnityEditor.InspectorWindow");
|
||||
typeInspectorWindow.GetMethod("RepaintAllInspectors", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null);
|
||||
}
|
||||
|
||||
public static void ScheduleRepaintInspectors()
|
||||
{
|
||||
EditorApplication.update += RepaintInspectors;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#if UNITY_2022_3_OR_NEWER
|
||||
public const string Style_ToolbarSearchTextField = "ToolbarSearchTextField";
|
||||
public const string Style_ToolbarSearchCancelButtonEmpty = "ToolbarSearchCancelButtonEmpty";
|
||||
public const string Style_ToolbarSearchCancelButton = "ToolbarSearchCancelButton";
|
||||
#else
|
||||
public const string Style_ToolbarSearchTextField = "ToolbarSeachTextField";
|
||||
public const string Style_ToolbarSearchCancelButtonEmpty = "ToolbarSeachCancelButtonEmpty";
|
||||
public const string Style_ToolbarSearchCancelButton = "ToolbarSeachCancelButton";
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df33c1000ac895241a433812e40a2096
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a500716e59f61824ba1fa6b418ce31a7
|
||||
folderAsset: yes
|
||||
timeCreated: 1461137613
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,20 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
[CustomEditor(typeof(LanguageSourceAsset))]
|
||||
public class LanguageSourceAssetInspector : LocalizationEditor
|
||||
{
|
||||
void OnEnable()
|
||||
{
|
||||
var newSource = target as LanguageSourceAsset;
|
||||
SerializedProperty propSource = serializedObject.FindProperty("mSource");
|
||||
|
||||
Custom_OnEnable(newSource.mSource, propSource);
|
||||
}
|
||||
public override LanguageSourceData GetSourceData()
|
||||
{
|
||||
return (target as LanguageSourceAsset).mSource;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f03a75bf70a306a4fb36646f24c1c1f1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,22 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
[CustomEditor(typeof(LanguageSource))]
|
||||
public class LanguageSourceInspector : LocalizationEditor
|
||||
{
|
||||
void OnEnable()
|
||||
{
|
||||
var newSource = target as LanguageSource;
|
||||
SerializedProperty propSource = serializedObject.FindProperty("mSource");
|
||||
|
||||
Custom_OnEnable(newSource.mSource, propSource);
|
||||
}
|
||||
|
||||
public override LanguageSourceData GetSourceData()
|
||||
{
|
||||
return (target as LanguageSource).mSource;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a441ed994a43a0a4a9d33be67a8d3f15
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,200 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public abstract partial class LocalizationEditor : UnityEditor.Editor
|
||||
{
|
||||
#region Variables
|
||||
|
||||
SerializedProperty mProp_Assets, mProp_Languages,
|
||||
mProp_Google_WebServiceURL, mProp_GoogleUpdateFrequency, mProp_GoogleUpdateDelay, mProp_Google_SpreadsheetKey, mProp_Google_SpreadsheetName, mProp_Google_Password,
|
||||
mProp_Spreadsheet_LocalFileName, mProp_Spreadsheet_LocalCSVSeparator, mProp_CaseInsensitiveTerms, mProp_Spreadsheet_LocalCSVEncoding,
|
||||
mProp_OnMissingTranslation, mProp_AppNameTerm, mProp_IgnoreDeviceLanguage, mProp_Spreadsheet_SpecializationAsRows, mProp_Spreadsheet_SortRows, mProp_GoogleInEditorCheckFrequency,
|
||||
mProp_HighlightLocalizedTargets, mProp_GoogleLiveSyncIsUptoDate, mProp_AllowUnloadingLanguages, mProp_GoogleUpdateSynchronization;
|
||||
|
||||
public static LanguageSourceData mLanguageSource;
|
||||
public static Object mLanguageSourceObject;
|
||||
public static LocalizationEditor mLanguageSourceEditor;
|
||||
public static UnityEditor.Editor mCurrentInspector;
|
||||
|
||||
static bool mIsParsing; // This is true when the editor is opening several scenes to avoid reparsing objects
|
||||
|
||||
#endregion
|
||||
|
||||
#region Variables GUI
|
||||
|
||||
GUIStyle Style_ToolBar_Big, Style_ToolBarButton_Big;
|
||||
|
||||
|
||||
public GUISkin CustomSkin;
|
||||
|
||||
static Vector3 mScrollPos_Languages;
|
||||
public static string mLanguages_NewLanguage = "";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Styles
|
||||
|
||||
public static GUIStyle Style_WrapTextField {
|
||||
get{
|
||||
if (mStyle_WrapTextField==null)
|
||||
{
|
||||
mStyle_WrapTextField = new GUIStyle(EditorStyles.textArea);
|
||||
mStyle_WrapTextField.wordWrap = true;
|
||||
mStyle_WrapTextField.fixedHeight = 0;
|
||||
}
|
||||
return mStyle_WrapTextField;
|
||||
}
|
||||
}
|
||||
static GUIStyle mStyle_WrapTextField;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Inspector
|
||||
|
||||
public void Custom_OnEnable( LanguageSourceData sourceData, SerializedProperty propSource)
|
||||
{
|
||||
bool ForceParse = mLanguageSource != sourceData;
|
||||
|
||||
mLanguageSource = sourceData;
|
||||
mLanguageSourceEditor = this;
|
||||
mCurrentInspector = this;
|
||||
|
||||
if (!LocalizationManager.Sources.Contains(mLanguageSource))
|
||||
LocalizationManager.UpdateSources();
|
||||
|
||||
mProp_Assets = propSource.FindPropertyRelative("Assets");
|
||||
mProp_Languages = propSource.FindPropertyRelative("mLanguages");
|
||||
mProp_Google_WebServiceURL = propSource.FindPropertyRelative("Google_WebServiceURL");
|
||||
mProp_GoogleUpdateFrequency = propSource.FindPropertyRelative("GoogleUpdateFrequency");
|
||||
mProp_GoogleUpdateSynchronization = propSource.FindPropertyRelative("GoogleUpdateSynchronization");
|
||||
mProp_GoogleInEditorCheckFrequency = propSource.FindPropertyRelative("GoogleInEditorCheckFrequency");
|
||||
mProp_GoogleUpdateDelay = propSource.FindPropertyRelative("GoogleUpdateDelay");
|
||||
mProp_Google_SpreadsheetKey = propSource.FindPropertyRelative("Google_SpreadsheetKey");
|
||||
mProp_Google_SpreadsheetName = propSource.FindPropertyRelative("Google_SpreadsheetName");
|
||||
mProp_Google_Password = propSource.FindPropertyRelative("Google_Password");
|
||||
mProp_CaseInsensitiveTerms = propSource.FindPropertyRelative("CaseInsensitiveTerms");
|
||||
mProp_Spreadsheet_LocalFileName = propSource.FindPropertyRelative("Spreadsheet_LocalFileName");
|
||||
mProp_Spreadsheet_LocalCSVSeparator = propSource.FindPropertyRelative("Spreadsheet_LocalCSVSeparator");
|
||||
mProp_Spreadsheet_LocalCSVEncoding = propSource.FindPropertyRelative("Spreadsheet_LocalCSVEncoding");
|
||||
mProp_Spreadsheet_SpecializationAsRows = propSource.FindPropertyRelative("Spreadsheet_SpecializationAsRows");
|
||||
mProp_Spreadsheet_SortRows = propSource.FindPropertyRelative("Spreadsheet_SortRows");
|
||||
mProp_OnMissingTranslation = propSource.FindPropertyRelative("OnMissingTranslation");
|
||||
mProp_AppNameTerm = propSource.FindPropertyRelative("mTerm_AppName");
|
||||
mProp_IgnoreDeviceLanguage = propSource.FindPropertyRelative("IgnoreDeviceLanguage");
|
||||
mProp_GoogleLiveSyncIsUptoDate = propSource.FindPropertyRelative("GoogleLiveSyncIsUptoDate");
|
||||
mProp_AllowUnloadingLanguages = propSource.FindPropertyRelative("_AllowUnloadingLanguages");
|
||||
|
||||
if (!mIsParsing)
|
||||
{
|
||||
if (string.IsNullOrEmpty(mLanguageSource.Google_SpreadsheetKey))
|
||||
mSpreadsheetMode = eSpreadsheetMode.Local;
|
||||
else
|
||||
mSpreadsheetMode = eSpreadsheetMode.Google;
|
||||
|
||||
mCurrentViewMode = mLanguageSource.mLanguages.Count>0 ? eViewMode.Keys : eViewMode.Languages;
|
||||
|
||||
UpdateSelectedKeys();
|
||||
|
||||
if (ForceParse || mParsedTerms.Count < mLanguageSource.mTerms.Count)
|
||||
{
|
||||
mSelectedCategories.Clear();
|
||||
ParseTerms(true, false, true);
|
||||
}
|
||||
}
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
LoadSelectedCategories();
|
||||
//UpgradeManager.EnablePlugins();
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
//LocalizationManager.LocalizeAll();
|
||||
SaveSelectedCategories();
|
||||
mLanguageSourceEditor = null;
|
||||
if (mCurrentInspector==this) mCurrentInspector = null;
|
||||
}
|
||||
|
||||
|
||||
void UpdateSelectedKeys()
|
||||
{
|
||||
// Remove all keys that are not in this source
|
||||
string trans;
|
||||
for (int i=mSelectedKeys.Count-1; i>=0; --i)
|
||||
if (!mLanguageSource.TryGetTranslation(mSelectedKeys[i], out trans))
|
||||
mSelectedKeys.RemoveAt(i);
|
||||
|
||||
// Remove all Categories that are not in this source
|
||||
/*var mCateg = mLanguageSource.GetCategories();
|
||||
for (int i=mSelectedCategories.Count-1; i>=0; --i)
|
||||
if (!mCateg.Contains(mSelectedCategories[i]))
|
||||
mSelectedCategories.RemoveAt(i);
|
||||
if (mSelectedCategories.Count==0)
|
||||
mSelectedCategories = mCateg;*/
|
||||
|
||||
if (mSelectedScenes.Count==0)
|
||||
mSelectedScenes.Add (Editor_GetCurrentScene());
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
// Load Test:
|
||||
/*if (mLanguageSource.mTerms.Count<40000)
|
||||
{
|
||||
mLanguageSource.mTerms.Clear();
|
||||
for (int i=0; i<40020; ++i)
|
||||
mLanguageSource.AddTerm("ahh"+i.ToString("00000"), eTermType.Text, false);
|
||||
mLanguageSource.UpdateDictionary();
|
||||
}*/
|
||||
//Profiler.maxNumberOfSamplesPerFrame = -1; // REMOVE ---------------------------------------------------
|
||||
|
||||
mIsParsing = false;
|
||||
|
||||
//#if UNITY_5_6_OR_NEWER
|
||||
// serializedObject.UpdateIfRequiredOrScript();
|
||||
//#else
|
||||
// serializedObject.UpdateIfDirtyOrScript();
|
||||
//#endif
|
||||
|
||||
if (mLanguageSource.mTerms.Count<1000)
|
||||
Undo.RecordObject(target, "LanguageSource");
|
||||
|
||||
//GUI.backgroundColor = Color.Lerp (Color.black, Color.gray, 1);
|
||||
//GUILayout.BeginVertical(LocalizeInspector.GUIStyle_Background);
|
||||
//GUI.backgroundColor = Color.white;
|
||||
|
||||
if (GUILayout.Button("Language Source", LocalizeInspector.GUIStyle_Header))
|
||||
{
|
||||
Application.OpenURL(LocalizeInspector.HelpURL_Documentation);
|
||||
}
|
||||
|
||||
InitializeStyles();
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
//GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
|
||||
//GUILayout.BeginVertical(LocalizeInspector.GUIStyle_Background);
|
||||
//GUI.backgroundColor = Color.white;
|
||||
OnGUI_Main();
|
||||
//GUILayout.EndVertical();
|
||||
|
||||
GUILayout.Space (10);
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUITools.OnGUI_Footer("I2 Localization", LocalizationManager.GetVersion(), LocalizeInspector.HelpURL_forum, LocalizeInspector.HelpURL_Documentation, LocalizeInspector.HelpURL_AssetStore);
|
||||
|
||||
//GUILayout.EndVertical();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
if (UnityEngine.Event.current.type == EventType.Repaint)
|
||||
{
|
||||
mTestAction = eTest_ActionType.None;
|
||||
mTestActionArg = null;
|
||||
mTestActionArg2 = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90c932abd0dc445448366dfe101408ba
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,107 @@
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
[CustomEditor(typeof(LocalizationParamsManager))]
|
||||
public class LocalizationParamsManagerInspector : UnityEditor.Editor
|
||||
{
|
||||
private ReorderableList mList;
|
||||
private SerializedProperty mProp_IsGlobalManager;
|
||||
|
||||
|
||||
private ReorderableList getList(SerializedObject serObject)
|
||||
{
|
||||
if (mList == null) {
|
||||
mList = new ReorderableList (serObject, serObject.FindProperty ("_Params"), true, true, true, true);
|
||||
mList.drawElementCallback = drawElementCallback;
|
||||
mList.drawHeaderCallback = drawHeaderCallback;
|
||||
mList.onAddCallback = addElementCallback;
|
||||
mList.onRemoveCallback = removeElementCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
mList.serializedProperty = serObject.FindProperty ("_Params");
|
||||
}
|
||||
return mList;
|
||||
}
|
||||
|
||||
private void addElementCallback( ReorderableList list )
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
var objParams = target as LocalizationParamsManager;
|
||||
objParams._Params.Add(new LocalizationParamsManager.ParamValue());
|
||||
list.index = objParams._Params.Count - 1;
|
||||
serializedObject.Update();
|
||||
}
|
||||
|
||||
private void removeElementCallback( ReorderableList list )
|
||||
{
|
||||
if (list.index < 0)
|
||||
return;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
var objParams = target as LocalizationParamsManager;
|
||||
objParams._Params.RemoveAt(list.index);
|
||||
serializedObject.Update();
|
||||
}
|
||||
|
||||
private void drawHeaderCallback(Rect rect)
|
||||
{
|
||||
GUI.Label(rect, "Parameters:");
|
||||
}
|
||||
|
||||
private void drawElementCallback(Rect rect, int index, bool isActive, bool isFocused)
|
||||
{
|
||||
var serializedElement = mList.serializedProperty.GetArrayElementAtIndex (index);
|
||||
var content = new GUIContent ();
|
||||
|
||||
Rect r = rect; r.xMax = r.xMin+40;
|
||||
GUI.Label(r, "Name");
|
||||
|
||||
r = rect; r.xMax = (r.xMax + r.xMin)/2 - 2; r.xMin = r.xMin+40;
|
||||
EditorGUI.PropertyField (r, serializedElement.FindPropertyRelative ("Name"),content);
|
||||
|
||||
r = rect; r.xMin = (r.xMax + r.xMin) / 2 + 2; r.xMax = r.xMin+40;
|
||||
GUI.Label(r, "Value");
|
||||
|
||||
r = rect; r.xMin = (r.xMax + r.xMin)/2 + 2 + 40;
|
||||
EditorGUI.PropertyField (r, serializedElement.FindPropertyRelative ("Value"), content);
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
mList = getList(serializedObject);
|
||||
mProp_IsGlobalManager = serializedObject.FindProperty("_IsGlobalManager");
|
||||
}
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
#else
|
||||
serializedObject.UpdateIfDirtyOrScript();
|
||||
#endif
|
||||
|
||||
GUI.backgroundColor = Color.Lerp (Color.black, Color.gray, 1);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_Background);
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
if (GUILayout.Button("Dynamic Parameters", LocalizeInspector.GUIStyle_Header))
|
||||
{
|
||||
Application.OpenURL(LocalizeInspector.HelpURL_Documentation);
|
||||
}
|
||||
|
||||
GUILayout.Space(5);
|
||||
mProp_IsGlobalManager.boolValue = EditorGUILayout.Popup(new GUIContent("Manager Type", "Local Manager only apply parameters to the Localize component in the same GameObject\n\nGlobal Manager apply parameters to all Localize components"), mProp_IsGlobalManager.boolValue ? 1 : 0, new[] { new GUIContent("Local"), new GUIContent("Global") }) == 1;
|
||||
|
||||
|
||||
GUILayout.Space(5);
|
||||
mList.DoLayoutList();
|
||||
|
||||
//EditorGUILayout.PropertyField(serializedObject.FindProperty("_AutoRegister"), new GUIContent("Auto Register"));
|
||||
|
||||
GUILayout.EndVertical();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93f1f9aecf6f7ed40ad1a082c22c47e5
|
||||
timeCreated: 1468111539
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
#if !UNITY_5_0 && !UNITY_5_1
|
||||
|
||||
[CustomEditor(typeof(LocalizeDropdown))]
|
||||
public class LocalizeDropdownInspector : UnityEditor.Editor
|
||||
{
|
||||
private ReorderableList mList;
|
||||
|
||||
private List<string> terms;
|
||||
|
||||
private ReorderableList getList(SerializedObject serObject)
|
||||
{
|
||||
if (mList == null) {
|
||||
mList = new ReorderableList (serObject, serObject.FindProperty ("_Terms"), true, true, true, true);
|
||||
mList.drawElementCallback = drawElementCallback;
|
||||
mList.drawHeaderCallback = drawHeaderCallback;
|
||||
mList.onAddCallback = addElementCallback;
|
||||
mList.onRemoveCallback = removeElementCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
mList.serializedProperty = serObject.FindProperty ("_Terms");
|
||||
}
|
||||
return mList;
|
||||
}
|
||||
|
||||
private void addElementCallback( ReorderableList list )
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
var objParams = target as LocalizeDropdown;
|
||||
objParams._Terms.Add(string.Empty);
|
||||
|
||||
list.index = objParams._Terms.Count - 1;
|
||||
|
||||
serializedObject.Update();
|
||||
}
|
||||
|
||||
private void removeElementCallback( ReorderableList list )
|
||||
{
|
||||
if (list.index < 0)
|
||||
return;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
var objParams = target as LocalizeDropdown;
|
||||
objParams._Terms.RemoveAt(list.index);
|
||||
|
||||
serializedObject.Update();
|
||||
}
|
||||
|
||||
private void drawHeaderCallback(Rect rect)
|
||||
{
|
||||
GUI.Label(rect, "Terms:");
|
||||
}
|
||||
|
||||
private void drawElementCallback(Rect rect, int index, bool isActive, bool isFocused)
|
||||
{
|
||||
var serializedElement = mList.serializedProperty.GetArrayElementAtIndex (index);
|
||||
|
||||
EditorGUI.BeginChangeCheck ();
|
||||
|
||||
var prvIndex = serializedElement.stringValue == "-" || serializedElement.stringValue == "" ? terms.Count - 1 :
|
||||
serializedElement.stringValue == " " ? terms.Count - 2 :
|
||||
terms.IndexOf(serializedElement.stringValue);
|
||||
|
||||
var newIndex = EditorGUI.Popup(rect, prvIndex, terms.ToArray());
|
||||
|
||||
if (EditorGUI.EndChangeCheck ())
|
||||
{
|
||||
if (newIndex == terms.Count - 1)
|
||||
serializedElement.stringValue = "-";
|
||||
else
|
||||
if (newIndex < 0 || newIndex == terms.Count - 2)
|
||||
serializedElement.stringValue = string.Empty;
|
||||
else
|
||||
serializedElement.stringValue = terms[newIndex];
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
mList = getList(serializedObject);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
#else
|
||||
serializedObject.UpdateIfDirtyOrScript();
|
||||
#endif
|
||||
terms = LocalizationManager.GetTermsList ();
|
||||
terms.Sort(StringComparer.OrdinalIgnoreCase);
|
||||
terms.Add("");
|
||||
terms.Add("<inferred from text>");
|
||||
terms.Add("<none>");
|
||||
|
||||
GUI.backgroundColor = Color.Lerp (Color.black, Color.gray, 1);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_Background);
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
if (GUILayout.Button("Localize DropDown", LocalizeInspector.GUIStyle_Header))
|
||||
{
|
||||
Application.OpenURL(LocalizeInspector.HelpURL_Documentation);
|
||||
}
|
||||
|
||||
|
||||
GUILayout.Space(5);
|
||||
mList.DoLayoutList();
|
||||
|
||||
GUILayout.Space (10);
|
||||
|
||||
GUITools.OnGUI_Footer("I2 Localization", LocalizationManager.GetVersion(), LocalizeInspector.HelpURL_forum, LocalizeInspector.HelpURL_Documentation, LocalizeInspector.HelpURL_AssetStore);
|
||||
|
||||
EditorGUIUtility.labelWidth = 0;
|
||||
|
||||
|
||||
GUILayout.EndVertical();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
terms = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65bbef08e6e42d24d9834945c3769202
|
||||
timeCreated: 1468111539
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,896 @@
|
||||
//#define UGUI
|
||||
//#define NGUI
|
||||
//#define DFGUI
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
[CustomEditor(typeof(Localize))]
|
||||
[CanEditMultipleObjects]
|
||||
public class LocalizeInspector : UnityEditor.Editor
|
||||
{
|
||||
#region Variables
|
||||
|
||||
Localize mLocalize;
|
||||
SerializedProperty mProp_mTerm, mProp_mTermSecondary,
|
||||
mProp_TranslatedObjects, mProp_LocalizeOnAwake, mProp_AlwaysForceLocalize, mProp_AllowLocalizedParameters, mProp_AllowParameters,
|
||||
mProp_IgnoreRTL, mProp_MaxCharactersInRTL, mProp_CorrectAlignmentForRTL, mProp_IgnoreNumbersInRTL, mProp_TermSuffix, mProp_TermPrefix, mProp_SeparateWords,
|
||||
mProp_CallbackEvent;
|
||||
|
||||
|
||||
bool mAllowEditKeyName;
|
||||
string mNewKeyName = "";
|
||||
|
||||
string[] mTermsArray;
|
||||
|
||||
|
||||
public static string HelpURL_forum = "http://goo.gl/Uiyu8C";//http://www.inter-illusion.com/forum/i2-localization";
|
||||
public static string HelpURL_Documentation = "http://www.inter-illusion.com/assets/I2LocalizationManual/I2LocalizationManual.html";
|
||||
public static string HelpURL_Tutorials = "http://inter-illusion.com/tools/i2-localization";
|
||||
public static string HelpURL_ReleaseNotes = "http://inter-illusion.com/forum/i2-localization/26-release-notes";
|
||||
public static string HelpURL_AssetStore = "https://www.assetstore.unity3d.com/#!/content/14884";
|
||||
|
||||
public static LocalizeInspector mLocalizeInspector;
|
||||
#endregion
|
||||
|
||||
#region Inspector
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
mLocalize = (Localize)target;
|
||||
mLocalizeInspector = this;
|
||||
LocalizationEditor.mCurrentInspector = this;
|
||||
mProp_mTerm = serializedObject.FindProperty("mTerm");
|
||||
mProp_mTermSecondary = serializedObject.FindProperty("mTermSecondary");
|
||||
mProp_TranslatedObjects = serializedObject.FindProperty("TranslatedObjects");
|
||||
mProp_IgnoreRTL = serializedObject.FindProperty("IgnoreRTL");
|
||||
mProp_SeparateWords = serializedObject.FindProperty("AddSpacesToJoinedLanguages");
|
||||
mProp_MaxCharactersInRTL = serializedObject.FindProperty ("MaxCharactersInRTL");
|
||||
mProp_IgnoreNumbersInRTL = serializedObject.FindProperty("IgnoreNumbersInRTL");
|
||||
mProp_CorrectAlignmentForRTL = serializedObject.FindProperty ("CorrectAlignmentForRTL");
|
||||
mProp_LocalizeOnAwake = serializedObject.FindProperty("LocalizeOnAwake");
|
||||
mProp_AlwaysForceLocalize = serializedObject.FindProperty("AlwaysForceLocalize");
|
||||
mProp_TermSuffix = serializedObject.FindProperty("TermSuffix");
|
||||
mProp_TermPrefix = serializedObject.FindProperty("TermPrefix");
|
||||
mProp_CallbackEvent = serializedObject.FindProperty("LocalizeEvent");
|
||||
mProp_AllowLocalizedParameters = serializedObject.FindProperty("AllowLocalizedParameters");
|
||||
mProp_AllowParameters = serializedObject.FindProperty("AllowParameters");
|
||||
|
||||
|
||||
if (LocalizationManager.Sources.Count==0)
|
||||
LocalizationManager.UpdateSources();
|
||||
//LocalizationEditor.ParseTerms (true);
|
||||
|
||||
//mGUI_ShowReferences = (mLocalize.TranslatedObjects!=null && mLocalize.TranslatedObjects.Length>0);
|
||||
//mGUI_ShowCallback = (mLocalize.LocalizeCallBack.Target!=null);
|
||||
//mGUI_ShowTems = true;
|
||||
LocalizationEditor.mKeysDesc_AllowEdit = false;
|
||||
GUI_SelectedTerm = 0;
|
||||
mNewKeyName = mLocalize.Term;
|
||||
|
||||
if (mLocalize.Source != null)
|
||||
LocalizationEditor.mLanguageSource = mLocalize.Source.SourceData;
|
||||
else
|
||||
{
|
||||
if (LocalizationManager.Sources.Count==0)
|
||||
LocalizationManager.UpdateSources();
|
||||
LocalizationEditor.mLanguageSource = LocalizationManager.GetSourceContaining( mLocalize.Term );
|
||||
}
|
||||
|
||||
//UpgradeManager.EnablePlugins();
|
||||
LocalizationEditor.ApplyInferredTerm (mLocalize);
|
||||
RemoveUnusedReferences(mLocalize);
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
mLocalizeInspector = null;
|
||||
if (LocalizationEditor.mCurrentInspector == this) LocalizationEditor.mCurrentInspector = null;
|
||||
|
||||
|
||||
if (mLocalize == null)
|
||||
return;
|
||||
|
||||
//#if TextMeshPro
|
||||
//string previous = null;
|
||||
|
||||
//if (!Application.isPlaying && !string.IsNullOrEmpty(mLocalize.TMP_previewLanguage))
|
||||
//{
|
||||
// previous = LocalizationManager.CurrentLanguage;
|
||||
// LocalizationManager.PreviewLanguage( mLocalize.TMP_previewLanguage );
|
||||
//}
|
||||
//#endif
|
||||
|
||||
//mLocalize.OnLocalize();
|
||||
|
||||
// Revert the preview language
|
||||
// except when in TMPro and not changing to another GameObject (TMPro has a bug where any change causes the inspector to Disable and Enable)
|
||||
if (!mLocalize.mLocalizeTargetName.Contains("LocalizeTarget_TextMeshPro") || Selection.activeGameObject==null || !Selection.gameObjects.Contains(mLocalize.gameObject))
|
||||
{
|
||||
LocalizationManager.LocalizeAll();
|
||||
}
|
||||
|
||||
//#if TextMeshPro
|
||||
//if (!string.IsNullOrEmpty(previous))
|
||||
//{
|
||||
// LocalizationManager.PreviewLanguage(previous);
|
||||
// mLocalize.TMP_previewLanguage = null;
|
||||
//}
|
||||
//#endif
|
||||
|
||||
RemoveUnusedReferences(mLocalize);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
Undo.RecordObject(target, "Localize");
|
||||
|
||||
//GUI.backgroundColor = Color.Lerp (Color.black, Color.gray, 1);
|
||||
//GUILayout.BeginVertical(GUIStyle_Background, GUILayout.Height(1));
|
||||
//GUI.backgroundColor = Color.white;
|
||||
|
||||
if (GUILayout.Button("Localize", GUIStyle_Header))
|
||||
{
|
||||
//Application.OpenURL(HelpURL_Documentation);
|
||||
}
|
||||
GUILayout.Space(-10);
|
||||
|
||||
LocalizationManager.UpdateSources();
|
||||
|
||||
if (LocalizationManager.Sources.Count==0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Unable to find a Language Source.", MessageType.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
OnGUI_Target ();
|
||||
GUILayout.Space(10);
|
||||
OnGUI_Terms();
|
||||
|
||||
//if (mGUI_ShowTems || mGUI_ShowReferences) GUILayout.Space(5);
|
||||
|
||||
OnGUI_References();
|
||||
|
||||
if (mLocalize.mGUI_ShowReferences || mLocalize.mGUI_ShowCallback) GUILayout.Space(10);
|
||||
|
||||
//Localize loc = target as Localize;
|
||||
|
||||
//--[ Localize Callback ]----------------------
|
||||
EditorGUILayout.PropertyField(mProp_CallbackEvent, new GUIContent("On Localize Callback"));
|
||||
|
||||
//string HeaderTitle = "On Localize Call:";
|
||||
//if (!mLocalize.mGUI_ShowCallback && loc.LocalizeCallBack.Target!=null && !string.IsNullOrEmpty(loc.LocalizeCallBack.MethodName))
|
||||
// HeaderTitle = string.Concat(HeaderTitle, " <b>",loc.LocalizeCallBack.Target.name, ".</b><i>", loc.LocalizeCallBack.MethodName, "</i>");
|
||||
//mLocalize.mGUI_ShowCallback = GUITools.DrawHeader(HeaderTitle, mLocalize.mGUI_ShowCallback);
|
||||
//if (mLocalize.mGUI_ShowCallback)
|
||||
//{
|
||||
// GUITools.BeginContents();
|
||||
// DrawEventCallBack( loc.LocalizeCallBack, loc );
|
||||
// GUITools.EndContents();
|
||||
//}
|
||||
}
|
||||
OnGUI_Source ();
|
||||
|
||||
GUILayout.Space (10);
|
||||
|
||||
GUITools.OnGUI_Footer("I2 Localization", LocalizationManager.GetVersion(), HelpURL_forum, HelpURL_Documentation, HelpURL_AssetStore);
|
||||
|
||||
//GUILayout.EndVertical();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
if (UnityEngine.Event.current.type == EventType.Repaint)
|
||||
{
|
||||
LocalizationEditor.mTestAction = LocalizationEditor.eTest_ActionType.None;
|
||||
LocalizationEditor.mTestActionArg = null;
|
||||
LocalizationEditor.mTestActionArg2 = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
|
||||
void OnGUI_References()
|
||||
{
|
||||
if (mLocalize.mGUI_ShowReferences = GUITools.DrawHeader ("References", mLocalize.mGUI_ShowReferences))
|
||||
{
|
||||
GUITools.BeginContents();
|
||||
|
||||
bool canTest = UnityEngine.Event.current.type == EventType.Repaint;
|
||||
|
||||
var testAddObj = canTest && LocalizationEditor.mTestAction == LocalizationEditor.eTest_ActionType.Button_Assets_Add ? (Object)LocalizationEditor.mTestActionArg : null;
|
||||
var testReplaceIndx = canTest && LocalizationEditor.mTestAction == LocalizationEditor.eTest_ActionType.Button_Assets_Replace ? (int)LocalizationEditor.mTestActionArg : -1;
|
||||
var testReplaceObj = canTest && LocalizationEditor.mTestAction == LocalizationEditor.eTest_ActionType.Button_Assets_Replace ? (Object)LocalizationEditor.mTestActionArg2 : null;
|
||||
var testDeleteIndx = canTest && LocalizationEditor.mTestAction == LocalizationEditor.eTest_ActionType.Button_Assets_Delete ? (int)LocalizationEditor.mTestActionArg : -1;
|
||||
|
||||
bool changed = GUITools.DrawObjectsArray( mProp_TranslatedObjects, false, false, true, testAddObj, testReplaceObj, testReplaceIndx, testDeleteIndx);
|
||||
if (changed)
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
foreach (var obj in serializedObject.targetObjects)
|
||||
(obj as Localize).UpdateAssetDictionary();
|
||||
}
|
||||
|
||||
GUITools.EndContents();
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveUnusedReferences(Localize cmp)
|
||||
{
|
||||
cmp.TranslatedObjects.RemoveAll(x => !IsUsingReference(LocalizationManager.GetTermData(cmp.Term), x) && !IsUsingReference(LocalizationManager.GetTermData(cmp.SecondaryTerm), x));
|
||||
if (cmp.TranslatedObjects.Count != cmp.mAssetDictionary.Count)
|
||||
cmp.UpdateAssetDictionary();
|
||||
}
|
||||
|
||||
bool IsUsingReference(TermData termData, Object obj )
|
||||
{
|
||||
if (obj == null || termData==null) return false;
|
||||
|
||||
string objName = obj.name;
|
||||
foreach (string translation in termData.Languages)
|
||||
{
|
||||
if (translation != null && translation.Contains(objName))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Terms
|
||||
|
||||
int GUI_SelectedTerm;
|
||||
void OnGUI_Terms()
|
||||
{
|
||||
if ((mLocalize.mGUI_ShowTems=GUITools.DrawHeader ("Terms", mLocalize.mGUI_ShowTems)))
|
||||
{
|
||||
//--[ tabs: Main and Secondary Terms ]----------------
|
||||
int oldTab = GUI_SelectedTerm;
|
||||
if (mLocalize.mLocalizeTarget!=null && mLocalize.mLocalizeTarget.CanUseSecondaryTerm())
|
||||
{
|
||||
GUI_SelectedTerm = GUITools.DrawTabs (GUI_SelectedTerm, new[]{"Main", "Secondary"});
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI_SelectedTerm = 0;
|
||||
GUITools.DrawTabs (GUI_SelectedTerm, new[]{"Main", ""});
|
||||
}
|
||||
|
||||
GUITools.BeginContents();
|
||||
|
||||
TermData termData = null;
|
||||
|
||||
if (GUI_SelectedTerm==0) termData = OnGUI_PrimaryTerm( oldTab!=GUI_SelectedTerm );
|
||||
else termData = OnGUI_SecondaryTerm(oldTab!=GUI_SelectedTerm);
|
||||
|
||||
GUITools.EndContents();
|
||||
|
||||
//--[ Modifier ]-------------
|
||||
if (mLocalize.Term != "-" && termData!=null && termData.TermType==eTermType.Text)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Prefix:");
|
||||
EditorGUILayout.PropertyField(mProp_TermPrefix, GUITools.EmptyContent);
|
||||
GUILayout.Label("Suffix:");
|
||||
EditorGUILayout.PropertyField(mProp_TermSuffix, GUITools.EmptyContent);
|
||||
GUILayout.EndHorizontal();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
if (targets != null)
|
||||
{
|
||||
foreach (var t in targets)
|
||||
if (t as Localize != null)
|
||||
(t as Localize).OnLocalize(true);
|
||||
}
|
||||
};
|
||||
}
|
||||
EditorGUI.BeginChangeCheck();
|
||||
int val = EditorGUILayout.Popup("Modifier", GUI_SelectedTerm == 0 ? (int)mLocalize.PrimaryTermModifier : (int)mLocalize.SecondaryTermModifier, Enum.GetNames(typeof(Localize.TermModification)));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.FindProperty(GUI_SelectedTerm == 0 ? "PrimaryTermModifier" : "SecondaryTermModifier").enumValueIndex = val;
|
||||
GUI.changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
OnGUI_Options();
|
||||
//--[ OnAwake vs OnEnable ]-------------
|
||||
//GUILayout.BeginHorizontal();
|
||||
//mProp_LocalizeOnAwake.boolValue = GUILayout.Toggle(mProp_LocalizeOnAwake.boolValue, new GUIContent(" Pre-Localize on Awake", "Localizing on Awake could result in a lag when the level is loaded but faster later when objects are enabled. If false, it will Localize OnEnable, so will yield faster level load but could have a lag when screens are enabled"));
|
||||
//GUILayout.FlexibleSpace();
|
||||
//if (mLocalize.HasCallback())
|
||||
//{
|
||||
// GUI.enabled = false;
|
||||
// GUILayout.Toggle(true, new GUIContent(" Force Localize", "Enable this when the translations have parameters (e.g. Thew winner is {[WINNER}]) to prevent any optimization that could prevent updating the translation when the object is enabled"));
|
||||
// GUI.enabled = true;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// mProp_AlwaysForceLocalize.boolValue = GUILayout.Toggle(mProp_AlwaysForceLocalize.boolValue, new GUIContent(" Force Localize", "Enable this when the translations have parameters (e.g. Thew winner is {[WINNER}]) to prevent any optimization that could prevent updating the translation when the object is enabled"));
|
||||
//}
|
||||
//GUILayout.EndHorizontal();
|
||||
|
||||
//--[ Right To Left ]-------------
|
||||
if (!mLocalize.IgnoreRTL && mLocalize.Term!="-" && termData != null && termData.TermType == eTermType.Text)
|
||||
{
|
||||
GUILayout.BeginVertical("Box");
|
||||
//GUILayout.BeginHorizontal();
|
||||
// mProp_IgnoreRTL.boolValue = GUILayout.Toggle(mProp_IgnoreRTL.boolValue, new GUIContent(" Ignore Right To Left", "Arabic and other RTL languages require processing them so they render correctly, this toogle allows ignoring that processing (in case you are doing it manually during a callback)"));
|
||||
// GUILayout.FlexibleSpace();
|
||||
// mProp_SeparateWords.boolValue = GUILayout.Toggle(mProp_SeparateWords.boolValue, new GUIContent(" Separate Words", " Some languages (e.g. Chinese, Japanese and Thai) don't add spaces to their words (all characters are placed toguether), enabling this checkbox, will add spaces to all characters to allow wrapping long texts into multiple lines."));
|
||||
//GUILayout.EndHorizontal();
|
||||
{
|
||||
mProp_MaxCharactersInRTL.intValue = EditorGUILayout.IntField( new GUIContent("Max line length", "If the language is Right To Left, long lines will be split at this length and the RTL fix will be applied to each line, this should be set to the maximum number of characters that fit in this text width. 0 disables the per line fix"), mProp_MaxCharactersInRTL.intValue );
|
||||
GUILayout.BeginHorizontal();
|
||||
mProp_CorrectAlignmentForRTL.boolValue = GUILayout.Toggle(mProp_CorrectAlignmentForRTL.boolValue, new GUIContent(" Adjust Alignment", "Right-align when Right-To-Left Language, and Left-Align otherwise") );
|
||||
GUILayout.FlexibleSpace();
|
||||
mProp_IgnoreNumbersInRTL.boolValue = GUILayout.Toggle(mProp_IgnoreNumbersInRTL.boolValue, new GUIContent(" Ignore Numbers", "Preserve numbers as latin characters instead of converting them"));
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
|
||||
////GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_Options()
|
||||
{
|
||||
int mask = 0;
|
||||
if (mProp_LocalizeOnAwake.boolValue) mask |= 1 << 0;
|
||||
if (mProp_AlwaysForceLocalize.boolValue) mask |= 1 << 1;
|
||||
if (mProp_AllowParameters.boolValue) mask |= 1 << 2;
|
||||
if (mProp_AllowLocalizedParameters.boolValue) mask |= 1 << 3;
|
||||
if (mProp_SeparateWords.boolValue) mask |= 1 << 4;
|
||||
if (mProp_IgnoreRTL.boolValue) mask |= 1 << 5;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
mask = EditorGUILayout.MaskField(new GUIContent("Options"), mask, new []{
|
||||
"Localize On Awake",
|
||||
"Force Localize",
|
||||
"Allow Parameters",
|
||||
"Allow Localized Parameters",
|
||||
"Separate Words",
|
||||
"Ignore RTL"
|
||||
});
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
mProp_LocalizeOnAwake.boolValue = (mask & (1 << 0))> 0;
|
||||
mProp_AlwaysForceLocalize.boolValue = (mask & (1 << 1))> 0;
|
||||
mProp_AllowParameters.boolValue = (mask & (1 << 2))> 0;
|
||||
mProp_AllowLocalizedParameters.boolValue = (mask & (1 << 3))> 0;
|
||||
mProp_SeparateWords.boolValue = (mask & (1 << 4))> 0;
|
||||
mProp_IgnoreRTL.boolValue = (mask & (1 << 5))> 0;
|
||||
}
|
||||
}
|
||||
|
||||
TermData OnGUI_PrimaryTerm( bool OnOpen )
|
||||
{
|
||||
string Key = mLocalize.mTerm;
|
||||
if (string.IsNullOrEmpty(Key))
|
||||
{
|
||||
string SecondaryTerm;
|
||||
mLocalize.GetFinalTerms( out Key, out SecondaryTerm );
|
||||
}
|
||||
|
||||
if (OnOpen) mNewKeyName = Key;
|
||||
if ( OnGUI_SelectKey( ref Key, string.IsNullOrEmpty(mLocalize.mTerm)))
|
||||
mProp_mTerm.stringValue = Key;
|
||||
return LocalizationEditor.OnGUI_Keys_Languages( Key, mLocalize );
|
||||
}
|
||||
|
||||
TermData OnGUI_SecondaryTerm( bool OnOpen )
|
||||
{
|
||||
string Key = mLocalize.mTermSecondary;
|
||||
|
||||
if (string.IsNullOrEmpty(Key))
|
||||
{
|
||||
string ss;
|
||||
mLocalize.GetFinalTerms( out ss, out Key );
|
||||
}
|
||||
|
||||
if (OnOpen) mNewKeyName = Key;
|
||||
if ( OnGUI_SelectKey( ref Key, string.IsNullOrEmpty(mLocalize.mTermSecondary)))
|
||||
mProp_mTermSecondary.stringValue = Key;
|
||||
return LocalizationEditor.OnGUI_Keys_Languages( Key, mLocalize, false );
|
||||
}
|
||||
|
||||
bool OnGUI_SelectKey( ref string Term, bool Inherited ) // Inherited==true means that the mTerm is empty and we are using the Label.text instead
|
||||
{
|
||||
GUILayout.Space (5);
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
GUI.changed = false;
|
||||
mAllowEditKeyName = GUILayout.Toggle(mAllowEditKeyName, "Term:", EditorStyles.foldout, GUILayout.ExpandWidth(false));
|
||||
if (GUI.changed && mAllowEditKeyName) {
|
||||
mNewKeyName = Term;
|
||||
mTermsArray = null;
|
||||
}
|
||||
|
||||
bool bChanged = false;
|
||||
|
||||
if (mTermsArray==null || Term!="-" && Array.IndexOf(mTermsArray, Term)<0)
|
||||
UpdateTermsList(Term);
|
||||
|
||||
if (Inherited)
|
||||
GUI.contentColor = Color.Lerp (Color.gray, Color.yellow, 0.1f);
|
||||
|
||||
int Index = Term=="-" || Term=="" ? mTermsArray.Length-1 : Array.IndexOf( mTermsArray, Term );
|
||||
|
||||
GUI.changed = false;
|
||||
|
||||
int newIndex = EditorGUILayout.Popup( Index, mTermsArray);
|
||||
|
||||
GUI.contentColor = Color.white;
|
||||
if (/*newIndex != Index && newIndex>=0*/GUI.changed)
|
||||
{
|
||||
GUI.changed = false;
|
||||
if (mLocalize.Source != null && newIndex == mTermsArray.Length - 4) //< show terms from all sources >
|
||||
{
|
||||
mLocalize.Source = null;
|
||||
mTermsArray = null;
|
||||
}
|
||||
else
|
||||
if (newIndex == mTermsArray.Length - 2) //<inferred from text>
|
||||
mNewKeyName = Term = string.Empty;
|
||||
else
|
||||
if (newIndex == mTermsArray.Length - 1) //<none>
|
||||
mNewKeyName = Term = "-";
|
||||
else
|
||||
mNewKeyName = Term = mTermsArray[newIndex];
|
||||
|
||||
|
||||
if (GUI_SelectedTerm==0)
|
||||
mLocalize.SetTerm (mNewKeyName);
|
||||
else
|
||||
mLocalize.SetTerm (null, mNewKeyName);
|
||||
mAllowEditKeyName = false;
|
||||
bChanged = true;
|
||||
}
|
||||
|
||||
LanguageSourceData source = LocalizationManager.GetSourceContaining(Term);
|
||||
TermData termData = source.GetTermData(Term);
|
||||
if (termData!=null)
|
||||
{
|
||||
if (Inherited)
|
||||
bChanged = true; // if the term its inferred and a matching term its found, then use that
|
||||
eTermType NewType = (eTermType)EditorGUILayout.EnumPopup(termData.TermType, GUILayout.Width(90));
|
||||
if (termData.TermType != NewType)
|
||||
termData.TermType = NewType;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (mAllowEditKeyName)
|
||||
{
|
||||
GUILayout.BeginHorizontal(GUILayout.Height (1));
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
if(mNewKeyName==null) mNewKeyName = string.Empty;
|
||||
|
||||
GUI.changed = false;
|
||||
mNewKeyName = EditorGUILayout.TextField(mNewKeyName, new GUIStyle(GUITools.Style_ToolbarSearchTextField), GUILayout.ExpandWidth(true));
|
||||
if (GUI.changed)
|
||||
{
|
||||
mTermsArray = null; // regenerate this array to apply filtering
|
||||
GUI.changed = false;
|
||||
}
|
||||
|
||||
if (GUILayout.Button (string.Empty, string.IsNullOrEmpty(mNewKeyName) ? GUITools.Style_ToolbarSearchCancelButtonEmpty : GUITools.Style_ToolbarSearchCancelButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
mTermsArray = null; // regenerate this array to apply filtering
|
||||
mNewKeyName = string.Empty;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
string ValidatedName = mNewKeyName;
|
||||
LanguageSourceData.ValidateFullTerm( ref ValidatedName );
|
||||
|
||||
bool CanUseNewName = source.GetTermData(ValidatedName)==null;
|
||||
GUI.enabled = !string.IsNullOrEmpty(mNewKeyName) && CanUseNewName;
|
||||
if (GUILayout.Button ("Create", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
mNewKeyName = ValidatedName;
|
||||
mTermsArray=null; // this recreates that terms array
|
||||
|
||||
LanguageSourceData Source = null;
|
||||
#if UNITY_EDITOR
|
||||
if (mLocalize.Source!=null)
|
||||
Source = mLocalize.Source.SourceData;
|
||||
#endif
|
||||
|
||||
if (Source==null)
|
||||
Source = LocalizationManager.Sources[0];
|
||||
Term = mNewKeyName;
|
||||
var data = Source.AddTerm( mNewKeyName, eTermType.Text, false );
|
||||
if (data.Languages.Length > 0)
|
||||
data.Languages[0] = mLocalize.GetMainTargetsText();
|
||||
Source.Editor_SetDirty();
|
||||
AssetDatabase.SaveAssets();
|
||||
mAllowEditKeyName = false;
|
||||
bChanged = true;
|
||||
GUIUtility.keyboardControl = 0;
|
||||
}
|
||||
GUI.enabled = termData!=null && !string.IsNullOrEmpty(mNewKeyName) && CanUseNewName;
|
||||
if (GUILayout.Button (new GUIContent("Rename","Renames the term in the source and updates every object using it in the current scene"), EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
mNewKeyName = ValidatedName;
|
||||
Term = mNewKeyName;
|
||||
mTermsArray=null; // this recreates that terms array
|
||||
mAllowEditKeyName = false;
|
||||
bChanged = true;
|
||||
LocalizationEditor.TermReplacements = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
LocalizationEditor.TermReplacements[ termData.Term ] = mNewKeyName;
|
||||
termData.Term = mNewKeyName;
|
||||
source.UpdateDictionary(true);
|
||||
LocalizationEditor.ReplaceTermsInCurrentScene();
|
||||
GUIUtility.keyboardControl = 0;
|
||||
EditorApplication.update += LocalizationEditor.DoParseTermsInCurrentScene;
|
||||
}
|
||||
GUI.enabled = true;
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
bChanged |= OnGUI_SelectKey_PreviewTerms ( ref Term);
|
||||
}
|
||||
|
||||
GUILayout.Space (5);
|
||||
return bChanged;
|
||||
}
|
||||
|
||||
void UpdateTermsList( string currentTerm )
|
||||
{
|
||||
List<string> Terms = mLocalize.Source==null ? LocalizationManager.GetTermsList() : mLocalize.Source.SourceData.GetTermsList();
|
||||
|
||||
// If there is a filter, remove all terms not matching that filter
|
||||
if (mAllowEditKeyName && !string.IsNullOrEmpty(mNewKeyName))
|
||||
{
|
||||
string Filter = mNewKeyName.ToUpper();
|
||||
for (int i=Terms.Count-1; i>=0; --i)
|
||||
if (!Terms[i].ToUpper().Contains(Filter) && Terms[i]!=currentTerm)
|
||||
Terms.RemoveAt(i);
|
||||
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(currentTerm) && currentTerm!="-" && !Terms.Contains(currentTerm))
|
||||
Terms.Add (currentTerm);
|
||||
|
||||
Terms.Sort(StringComparer.OrdinalIgnoreCase);
|
||||
Terms.Add("");
|
||||
if (mLocalize.Source != null)
|
||||
{
|
||||
Terms.Add("< Show Terms from all sources >");
|
||||
Terms.Add("");
|
||||
}
|
||||
Terms.Add("<inferred from text>");
|
||||
Terms.Add("<none>");
|
||||
|
||||
mTermsArray = Terms.ToArray();
|
||||
}
|
||||
|
||||
bool OnGUI_SelectKey_PreviewTerms ( ref string Term)
|
||||
{
|
||||
if (mTermsArray==null)
|
||||
UpdateTermsList(Term);
|
||||
|
||||
int nTerms = mTermsArray.Length;
|
||||
if (nTerms<=0)
|
||||
return false;
|
||||
|
||||
if (nTerms==1 && mTermsArray[0]==Term)
|
||||
return false;
|
||||
|
||||
bool bChanged = false;
|
||||
GUI.backgroundColor = Color.gray;
|
||||
GUILayout.BeginVertical (GUIStyle_OldTextArea);
|
||||
for (int i = 0, imax = Mathf.Min (nTerms, 3); i < imax; ++i)
|
||||
{
|
||||
ParsedTerm parsedTerm;
|
||||
int nUses = -1;
|
||||
if (LocalizationEditor.mParsedTerms.TryGetValue (mTermsArray [i], out parsedTerm))
|
||||
nUses = parsedTerm.Usage;
|
||||
|
||||
string FoundText = mTermsArray [i];
|
||||
if (nUses > 0)
|
||||
FoundText = string.Concat ("(", nUses, ") ", FoundText);
|
||||
|
||||
if (GUILayout.Button (FoundText, EditorStyles.miniLabel, GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 70)))
|
||||
{
|
||||
if (mTermsArray[i] == "<inferred from text>")
|
||||
mNewKeyName = Term = string.Empty;
|
||||
else
|
||||
if (mTermsArray[i] == "<none>")
|
||||
mNewKeyName = Term = "-";
|
||||
else
|
||||
if (mTermsArray[i] != "< Show Terms from all sources >")
|
||||
mNewKeyName = Term = mTermsArray[i];
|
||||
|
||||
//mNewKeyName = Term = (mTermsArray [i]=="<inferred from text>" ? string.Empty : mTermsArray [i]);
|
||||
GUIUtility.keyboardControl = 0;
|
||||
mAllowEditKeyName = false;
|
||||
bChanged = true;
|
||||
}
|
||||
}
|
||||
if (nTerms > 3)
|
||||
GUILayout.Label ("...");
|
||||
GUILayout.EndVertical ();
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
return bChanged;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Target
|
||||
|
||||
void OnGUI_Target()
|
||||
{
|
||||
List<string> TargetTypes = new List<string>();
|
||||
int CurrentTarget = -1;
|
||||
|
||||
mLocalize.FindTarget();
|
||||
|
||||
foreach (var desc in LocalizationManager.mLocalizeTargets)
|
||||
{
|
||||
if (desc.CanLocalize(mLocalize))
|
||||
{
|
||||
TargetTypes.Add(desc.Name);
|
||||
|
||||
if (mLocalize.mLocalizeTarget!=null && desc.GetTargetType() == mLocalize.mLocalizeTarget.GetType())
|
||||
CurrentTarget = TargetTypes.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (CurrentTarget==-1)
|
||||
{
|
||||
CurrentTarget = TargetTypes.Count;
|
||||
TargetTypes.Add("None");
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label ("Target:", GUILayout.Width (60));
|
||||
EditorGUI.BeginChangeCheck();
|
||||
int index = EditorGUILayout.Popup(CurrentTarget, TargetTypes.ToArray());
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
foreach (var obj in serializedObject.targetObjects)
|
||||
{
|
||||
var cmp = obj as Localize;
|
||||
if (cmp == null)
|
||||
continue;
|
||||
|
||||
if (cmp.mLocalizeTarget != null)
|
||||
DestroyImmediate(cmp.mLocalizeTarget);
|
||||
cmp.mLocalizeTarget = null;
|
||||
|
||||
foreach (var desc in LocalizationManager.mLocalizeTargets)
|
||||
{
|
||||
if (desc.Name == TargetTypes[index])
|
||||
{
|
||||
cmp.mLocalizeTarget = desc.CreateTarget(cmp);
|
||||
cmp.mLocalizeTargetName = desc.GetTargetType().ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
serializedObject.Update();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Source
|
||||
|
||||
void OnGUI_Source()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
ILanguageSource currentSource = mLocalize.Source;
|
||||
if (currentSource==null)
|
||||
{
|
||||
LanguageSourceData source = LocalizationManager.GetSourceContaining(mLocalize.Term);
|
||||
currentSource = source==null ? null : source.owner;
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Open Source", EditorStyles.toolbarButton, GUILayout.Width (100)))
|
||||
{
|
||||
Selection.activeObject = currentSource as Object;
|
||||
|
||||
string sTerm, sSecondary;
|
||||
mLocalize.GetFinalTerms( out sTerm, out sSecondary );
|
||||
if (GUI_SelectedTerm==1) sTerm = sSecondary;
|
||||
LocalizationEditor.mKeyToExplore = sTerm;
|
||||
}
|
||||
|
||||
GUILayout.Space (2);
|
||||
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
EditorGUI.BeginChangeCheck ();
|
||||
if (mLocalize.Source == null)
|
||||
{
|
||||
GUI.contentColor = Color.Lerp (Color.gray, Color.yellow, 0.1f);
|
||||
}
|
||||
Object obj = EditorGUILayout.ObjectField(currentSource as Object, typeof(Object), true);
|
||||
GUI.contentColor = Color.white;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
ILanguageSource NewSource = obj as ILanguageSource;
|
||||
if (NewSource == null && obj as GameObject != null)
|
||||
{
|
||||
NewSource = (obj as GameObject).GetComponent<LanguageSource>();
|
||||
}
|
||||
|
||||
mLocalize.Source = NewSource;
|
||||
string sTerm, sSecondary;
|
||||
mLocalize.GetFinalTerms(out sTerm, out sSecondary);
|
||||
if (GUI_SelectedTerm == 1) sTerm = sSecondary;
|
||||
UpdateTermsList(sTerm);
|
||||
}
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Detect", "Finds the LanguageSource containing the selected term, the term list will now only show terms inside that source."), EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
string sTerm, sSecondary;
|
||||
mLocalize.GetFinalTerms(out sTerm, out sSecondary);
|
||||
if (GUI_SelectedTerm == 1) sTerm = sSecondary;
|
||||
|
||||
var data = LocalizationManager.GetSourceContaining(sTerm, false);
|
||||
mLocalize.Source = data==null ? null : data.owner;
|
||||
mTermsArray = null;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Event CallBack
|
||||
|
||||
//public void DrawEventCallBack( EventCallback CallBack, Localize loc )
|
||||
//{
|
||||
//if (CallBack==null)
|
||||
// return;
|
||||
|
||||
//GUI.changed = false;
|
||||
|
||||
//GUILayout.BeginHorizontal();
|
||||
//GUILayout.Label("Target:", GUILayout.ExpandWidth(false));
|
||||
//CallBack.Target = EditorGUILayout.ObjectField( CallBack.Target, typeof(MonoBehaviour), true) as MonoBehaviour;
|
||||
//GUILayout.EndHorizontal();
|
||||
|
||||
//if (CallBack.Target!=null)
|
||||
//{
|
||||
// GameObject GO = CallBack.Target.gameObject;
|
||||
// List<MethodInfo> Infos = new List<MethodInfo>();
|
||||
|
||||
// var targets = GO.GetComponents(typeof(MonoBehaviour));
|
||||
// foreach (var behavior in targets)
|
||||
// Infos.AddRange( behavior.GetType().GetMethods() );
|
||||
|
||||
// List<string> Methods = new List<string>();
|
||||
|
||||
// for (int i = 0, imax=Infos.Count; i<imax; ++i)
|
||||
// {
|
||||
// MethodInfo mi = Infos[i];
|
||||
|
||||
// if (IsValidMethod(mi))
|
||||
// Methods.Add (mi.Name);
|
||||
// }
|
||||
|
||||
// int Index = Methods.IndexOf(CallBack.MethodName);
|
||||
|
||||
// int NewIndex = EditorGUILayout.Popup(Index, Methods.ToArray(), GUILayout.ExpandWidth(true));
|
||||
// if (NewIndex!=Index)
|
||||
// CallBack.MethodName = Methods[ NewIndex ];
|
||||
//}
|
||||
//if (GUI.changed)
|
||||
//{
|
||||
// GUI.changed = false;
|
||||
// EditorUtility.SetDirty(loc);
|
||||
// //UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty() EditorApplication.MakeSceneDirty();
|
||||
//}
|
||||
//}
|
||||
|
||||
static bool IsValidMethod( MethodInfo mi )
|
||||
{
|
||||
if (mi.DeclaringType == typeof(MonoBehaviour) || mi.ReturnType != typeof(void))
|
||||
return false;
|
||||
|
||||
ParameterInfo[] Params = mi.GetParameters ();
|
||||
if (Params.Length == 0) return true;
|
||||
if (Params.Length > 1) return false;
|
||||
|
||||
if (Params [0].ParameterType.IsSubclassOf (typeof(Object))) return true;
|
||||
if (Params [0].ParameterType == typeof(Object)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Styles
|
||||
|
||||
public static GUIStyle GUIStyle_Header {
|
||||
get{
|
||||
if (mGUIStyle_Header==null)
|
||||
{
|
||||
mGUIStyle_Header = new GUIStyle("HeaderLabel");
|
||||
mGUIStyle_Header.fontSize = 25;
|
||||
mGUIStyle_Header.normal.textColor = Color.Lerp(Color.white, Color.gray, 0.5f);
|
||||
mGUIStyle_Header.fontStyle = FontStyle.BoldAndItalic;
|
||||
mGUIStyle_Header.alignment = TextAnchor.UpperCenter;
|
||||
}
|
||||
return mGUIStyle_Header;
|
||||
}
|
||||
}
|
||||
static GUIStyle mGUIStyle_Header;
|
||||
|
||||
public static GUIStyle GUIStyle_SubHeader {
|
||||
get{
|
||||
if (mGUIStyle_SubHeader==null)
|
||||
{
|
||||
mGUIStyle_SubHeader = new GUIStyle("HeaderLabel");
|
||||
mGUIStyle_SubHeader.fontSize = 13;
|
||||
mGUIStyle_SubHeader.fontStyle = FontStyle.Normal;
|
||||
mGUIStyle_SubHeader.margin.top = -50;
|
||||
mGUIStyle_SubHeader.alignment = TextAnchor.UpperCenter;
|
||||
}
|
||||
return mGUIStyle_SubHeader;
|
||||
}
|
||||
}
|
||||
static GUIStyle mGUIStyle_SubHeader;
|
||||
|
||||
public static GUIStyle GUIStyle_Background {
|
||||
get{
|
||||
if (mGUIStyle_Background==null)
|
||||
{
|
||||
mGUIStyle_Background = new GUIStyle(EditorStyles.textArea);
|
||||
mGUIStyle_Background.fixedHeight = 0;
|
||||
mGUIStyle_Background.overflow.left = 50;
|
||||
mGUIStyle_Background.overflow.right = 50;
|
||||
mGUIStyle_Background.overflow.top = -5;
|
||||
mGUIStyle_Background.overflow.bottom = 0;
|
||||
}
|
||||
return mGUIStyle_Background;
|
||||
}
|
||||
}
|
||||
static GUIStyle mGUIStyle_Background;
|
||||
|
||||
public static GUIStyle GUIStyle_OldTextArea
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mGUIStyle_OldTextArea == null)
|
||||
{
|
||||
mGUIStyle_OldTextArea = new GUIStyle(EditorStyles.textArea);
|
||||
mGUIStyle_OldTextArea.fixedHeight = 0;
|
||||
}
|
||||
return mGUIStyle_OldTextArea;
|
||||
}
|
||||
}
|
||||
static GUIStyle mGUIStyle_OldTextArea;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 675119279b2a30245801272112cfbe38
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,29 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
[CustomEditor(typeof(ResourceManager))]
|
||||
public class ResourceManagerInspector : UnityEditor.Editor
|
||||
{
|
||||
SerializedProperty mAssets;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
UpgradeManager.EnablePlugins();
|
||||
mAssets = serializedObject.FindProperty("Assets");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
GUILayout.Space(5);
|
||||
GUITools.DrawHeader("Assets:", true);
|
||||
GUITools.BeginContents();
|
||||
///GUILayout.Label ("Assets:");
|
||||
GUITools.DrawObjectsArray( mAssets );
|
||||
GUITools.EndContents();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba2fdf8face79dd4f9e1ed80448db843
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
[CustomEditor(typeof(SetLanguage))]
|
||||
public class SetLanguageInspector : UnityEditor.Editor
|
||||
{
|
||||
public SetLanguage setLan;
|
||||
public SerializedProperty mProp_Language;
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
setLan = (SetLanguage)target;
|
||||
mProp_Language = serializedObject.FindProperty("_Language");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
string[] Languages;
|
||||
LanguageSource sourceObj = setLan.mSource;
|
||||
if (sourceObj == null)
|
||||
{
|
||||
LocalizationManager.UpdateSources();
|
||||
Languages = LocalizationManager.GetAllLanguages().ToArray();
|
||||
Array.Sort(Languages);
|
||||
}
|
||||
else
|
||||
{
|
||||
Languages = sourceObj.mSource.GetLanguages().ToArray();
|
||||
Array.Sort(Languages);
|
||||
}
|
||||
|
||||
int index = Array.IndexOf(Languages, mProp_Language.stringValue);
|
||||
|
||||
GUI.changed = false;
|
||||
index = EditorGUILayout.Popup("Language", index, Languages);
|
||||
if (GUI.changed)
|
||||
{
|
||||
if (index<0 || index>=Languages.Length)
|
||||
mProp_Language.stringValue = string.Empty;
|
||||
else
|
||||
mProp_Language.stringValue = Languages[index];
|
||||
GUI.changed = false;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
GUILayout.Space(5);
|
||||
if (setLan.mSource==null) GUI.contentColor = Color.Lerp (Color.gray, Color.yellow, 0.1f);
|
||||
sourceObj = EditorGUILayout.ObjectField("Language Source:", sourceObj, typeof(LanguageSource), true) as LanguageSource;
|
||||
GUI.contentColor = Color.white;
|
||||
|
||||
if (GUI.changed)
|
||||
setLan.mSource = sourceObj;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7af58b4da44670e47a509c59754e8c2b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
[CustomPropertyDrawer (typeof (TermsPopup))]
|
||||
public class TermsPopup_Drawer : PropertyDrawer
|
||||
{
|
||||
GUIContent[] mTerms_Context;
|
||||
int nFramesLeftBeforeUpdate;
|
||||
string mPrevFilter;
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
var filter = ((TermsPopup)attribute).Filter;
|
||||
ShowGUICached(position, property, label, null, filter, ref mTerms_Context, ref nFramesLeftBeforeUpdate, ref mPrevFilter);
|
||||
}
|
||||
|
||||
public static bool ShowGUI(Rect position, SerializedProperty property, GUIContent label, LanguageSourceData source, string filter = "")
|
||||
{
|
||||
GUIContent[] terms=null;
|
||||
int framesLeftBeforeUpdate=0;
|
||||
string prevFilter = null;
|
||||
|
||||
return ShowGUICached(position, property, label, source, filter, ref terms, ref framesLeftBeforeUpdate, ref prevFilter);
|
||||
}
|
||||
|
||||
public static bool ShowGUICached(Rect position, SerializedProperty property, GUIContent label, LanguageSourceData source, string filter, ref GUIContent[] terms_Contexts, ref int framesBeforeUpdating, ref string prevFilter)
|
||||
{
|
||||
UpdateTermsCache(source, filter, ref terms_Contexts, ref framesBeforeUpdating, ref prevFilter);
|
||||
|
||||
label = EditorGUI.BeginProperty(position, label, property);
|
||||
|
||||
EditorGUI.BeginChangeCheck ();
|
||||
|
||||
var index = property.stringValue == "-" || property.stringValue == "" ? terms_Contexts.Length - 1 :
|
||||
property.stringValue == " " ? terms_Contexts.Length - 2 :
|
||||
GetTermIndex(terms_Contexts, property.stringValue);
|
||||
var newIndex = EditorGUI.Popup(position, label, index, terms_Contexts);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
property.stringValue = newIndex < 0 || newIndex == terms_Contexts.Length - 1 ? string.Empty : terms_Contexts[newIndex].text;
|
||||
if (newIndex == terms_Contexts.Length - 1)
|
||||
property.stringValue = "-";
|
||||
else
|
||||
if (newIndex < 0 || newIndex == terms_Contexts.Length - 2)
|
||||
property.stringValue = string.Empty;
|
||||
else
|
||||
property.stringValue = terms_Contexts[newIndex].text;
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
return true;
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
return false;
|
||||
}
|
||||
|
||||
static int GetTermIndex(GUIContent[] terms_Contexts, string term )
|
||||
{
|
||||
for (int i = 0; i < terms_Contexts.Length; ++i)
|
||||
if (terms_Contexts[i].text == term)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void UpdateTermsCache(LanguageSourceData source, string filter, ref GUIContent[] terms_Contexts, ref int framesBeforeUpdating, ref string prevFilter)
|
||||
{
|
||||
framesBeforeUpdating--;
|
||||
if (terms_Contexts!=null && framesBeforeUpdating>0 && filter==prevFilter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
framesBeforeUpdating = 60;
|
||||
prevFilter = filter;
|
||||
|
||||
var Terms = source == null ? LocalizationManager.GetTermsList() : source.GetTermsList();
|
||||
|
||||
if (string.IsNullOrEmpty(filter) == false)
|
||||
{
|
||||
Terms = Filter(Terms, filter);
|
||||
}
|
||||
|
||||
Terms.Sort(StringComparer.OrdinalIgnoreCase);
|
||||
Terms.Add("");
|
||||
Terms.Add("<inferred from text>");
|
||||
Terms.Add("<none>");
|
||||
|
||||
terms_Contexts = DisplayOptions(Terms);
|
||||
}
|
||||
|
||||
private static List<string> Filter(List<string> terms, string filter)
|
||||
{
|
||||
var filtered = new List<string>();
|
||||
for (var i = 0; i < terms.Count; i++)
|
||||
{
|
||||
var term = terms[i];
|
||||
if (term.Contains(filter))
|
||||
{
|
||||
filtered.Add(term);
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private static GUIContent[] DisplayOptions(IList<string> terms)
|
||||
{
|
||||
var options = new GUIContent[terms.Count];
|
||||
for (var i = 0; i < terms.Count; i++)
|
||||
{
|
||||
options[i] = new GUIContent(terms[i]);
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
[CustomPropertyDrawer(typeof(LocalizedString))]
|
||||
public class LocalizedStringDrawer : PropertyDrawer
|
||||
{
|
||||
GUIContent[] mTerms_Context;
|
||||
int nFramesLeftBeforeUpdate;
|
||||
string mPrevFilter;
|
||||
|
||||
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
var termRect = rect; termRect.xMax -= 50;
|
||||
var termProp = property.FindPropertyRelative("mTerm");
|
||||
TermsPopup_Drawer.ShowGUICached(termRect, termProp, label, null, "", ref mTerms_Context, ref nFramesLeftBeforeUpdate, ref mPrevFilter);
|
||||
|
||||
var maskRect = rect; maskRect.xMin = maskRect.xMax - 30;
|
||||
var termIgnoreRTL = property.FindPropertyRelative("mRTL_IgnoreArabicFix");
|
||||
var termConvertNumbers = property.FindPropertyRelative("mRTL_ConvertNumbers");
|
||||
var termDontLocalizeParams = property.FindPropertyRelative("m_DontLocalizeParameters");
|
||||
int mask = (termIgnoreRTL.boolValue ? 0 : 1) +
|
||||
(termConvertNumbers.boolValue ? 0 : 2) +
|
||||
(termDontLocalizeParams.boolValue ? 0 : 4);
|
||||
|
||||
int newMask = EditorGUI.MaskField(maskRect, mask, new[] { "Arabic Fix", "Ignore Numbers in RTL", "Localize Parameters" });
|
||||
if (newMask != mask)
|
||||
{
|
||||
termIgnoreRTL.boolValue = (newMask & 1) == 0;
|
||||
termConvertNumbers.boolValue = (newMask & 2) == 0;
|
||||
termDontLocalizeParams.boolValue = (newMask & 4) == 0;
|
||||
}
|
||||
|
||||
var showRect = rect; showRect.xMin = termRect.xMax; showRect.xMax=maskRect.xMin;
|
||||
bool enabled = GUI.enabled;
|
||||
GUI.enabled = enabled & (!string.IsNullOrEmpty (termProp.stringValue) && termProp.stringValue!="-");
|
||||
if (GUI.Button (showRect, "?"))
|
||||
{
|
||||
var source = LocalizationManager.GetSourceContaining(termProp.stringValue);
|
||||
LocalizationEditor.mKeyToExplore = termProp.stringValue;
|
||||
Selection.activeObject = source.ownerObject;
|
||||
}
|
||||
GUI.enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51c22a426b92fa84cb6ca7b75176da8a
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ad136296e8e6e14eaa2726ac1992b6c
|
||||
folderAsset: yes
|
||||
timeCreated: 1461137613
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,308 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
|
||||
#region Variables
|
||||
|
||||
public enum eViewMode { ImportExport, Keys, Languages, Tools, References }
|
||||
public static eViewMode mCurrentViewMode = eViewMode.Keys;
|
||||
|
||||
public enum eSpreadsheetMode { Local, Google }
|
||||
public eSpreadsheetMode mSpreadsheetMode = eSpreadsheetMode.Google;
|
||||
|
||||
|
||||
public static string mLocalizationMsg = "";
|
||||
public static MessageType mLocalizationMessageType = MessageType.None;
|
||||
|
||||
// These variables are for executing action from Unity Tests
|
||||
public enum eTest_ActionType { None, Button_AddLanguageFromPopup, Button_AddLanguageManual,
|
||||
Button_AddTerm_InTermsList, Button_AddSelectedTerms,
|
||||
Button_RemoveSelectedTerms, Button_DeleteTerm,
|
||||
Button_SelectTerms_All, Button_SelectTerms_None, Button_SelectTerms_Used, Button_SelectTerms_Missing,
|
||||
Button_Term_Translate, Button_Term_TranslateAll, Button_Languages_TranslateAll,
|
||||
Button_Assets_Add, Button_Assets_Replace, Button_Assets_Delete,
|
||||
Button_GoogleSpreadsheet_RefreshList, Button_GoogleSpreadsheet_Export, Button_GoogleSpreadsheet_Import
|
||||
}
|
||||
public static eTest_ActionType mTestAction = eTest_ActionType.None;
|
||||
public static object mTestActionArg, mTestActionArg2;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Editor
|
||||
|
||||
/*[MenuItem("Window/Localization", false)]
|
||||
public static void OpenLocalizationEditor()
|
||||
{
|
||||
EditorWindow.GetWindow<LocalizationEditor>(false, "Localization", true);
|
||||
}*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI
|
||||
|
||||
void InitializeStyles()
|
||||
{
|
||||
Style_ToolBar_Big = new GUIStyle(EditorStyles.toolbar);
|
||||
Style_ToolBar_Big.fixedHeight = Style_ToolBar_Big.fixedHeight*1.5f;
|
||||
|
||||
Style_ToolBarButton_Big = new GUIStyle(EditorStyles.toolbarButton);
|
||||
Style_ToolBarButton_Big.fixedHeight = Style_ToolBarButton_Big.fixedHeight*1.5f;
|
||||
}
|
||||
|
||||
|
||||
void OnGUI_Main()
|
||||
{
|
||||
OnGUI_Warning_SourceInScene();
|
||||
OnGUI_Warning_SourceInsidePluginsFolder();
|
||||
OnGUI_Warning_SourceNotUpToDate();
|
||||
|
||||
var prevViewMode = mCurrentViewMode;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
//OnGUI_ToggleEnumBig( "Spreadsheets", ref mCurrentViewMode, eViewMode.ImportExport, GUI.skin.GetStyle("CN EntryWarn").normal.background, "External Spreadsheet File or Service" );
|
||||
OnGUI_ToggleEnumBig( "Spreadsheets", ref mCurrentViewMode, eViewMode.ImportExport, null, "External Spreadsheet File or Service" );
|
||||
OnGUI_ToggleEnumBig( "Terms", ref mCurrentViewMode, eViewMode.Keys, null, null );
|
||||
OnGUI_ToggleEnumBig( "Languages", ref mCurrentViewMode, eViewMode.Languages, null, null );
|
||||
OnGUI_ToggleEnumBig( "Tools", ref mCurrentViewMode, eViewMode.Tools, null, null );
|
||||
OnGUI_ToggleEnumBig( "Assets", ref mCurrentViewMode, eViewMode.References, null, null );
|
||||
GUILayout.EndHorizontal();
|
||||
//GUILayout.Space(10);
|
||||
|
||||
switch (mCurrentViewMode)
|
||||
{
|
||||
case eViewMode.ImportExport : OnGUI_ImportExport(); break;
|
||||
case eViewMode.Keys : OnGUI_KeysList(); break;
|
||||
case eViewMode.Languages : OnGUI_Languages(); break;
|
||||
case eViewMode.Tools : OnGUI_Tools(prevViewMode != mCurrentViewMode); break;
|
||||
case eViewMode.References : OnGUI_References(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_ImportExport()
|
||||
{
|
||||
eSpreadsheetMode OldMode = mSpreadsheetMode;
|
||||
mSpreadsheetMode = (eSpreadsheetMode)GUITools.DrawShadowedTabs ((int)mSpreadsheetMode, new[]{"Local", "Google"});
|
||||
if (mSpreadsheetMode != OldMode)
|
||||
ClearErrors();
|
||||
|
||||
GUITools.BeginContents();
|
||||
switch (mSpreadsheetMode)
|
||||
{
|
||||
case eSpreadsheetMode.Local : OnGUI_Spreadsheet_Local(); break;
|
||||
case eSpreadsheetMode.Google : OnGUI_Spreadsheet_Google(); break;
|
||||
}
|
||||
GUITools.EndContents(false);
|
||||
}
|
||||
|
||||
void OnGUI_References()
|
||||
{
|
||||
EditorGUILayout.HelpBox("These are the assets that are referenced by the Terms and not in the Resources folder", MessageType.Info);
|
||||
|
||||
bool canTest = UnityEngine.Event.current.type == EventType.Repaint;
|
||||
|
||||
var testAddObj = canTest && mTestAction == eTest_ActionType.Button_Assets_Add ? (Object)mTestActionArg : null;
|
||||
var testReplaceIndx = canTest && mTestAction == eTest_ActionType.Button_Assets_Replace ? (int)mTestActionArg : -1;
|
||||
var testReplaceObj = canTest && mTestAction == eTest_ActionType.Button_Assets_Replace ? (Object)mTestActionArg2 : null;
|
||||
var testDeleteIndx = canTest && mTestAction == eTest_ActionType.Button_Assets_Delete ? (int)mTestActionArg : -1;
|
||||
|
||||
bool changed = GUITools.DrawObjectsArray( mProp_Assets, false, false, false, testAddObj, testReplaceObj, testReplaceIndx, testDeleteIndx);
|
||||
if (changed)
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
foreach (var obj in serializedObject.targetObjects)
|
||||
(obj as LanguageSource).mSource.UpdateAssetDictionary();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Misc
|
||||
|
||||
void OnGUI_ToggleEnumBig<Enum>( string text, ref Enum currentMode, Enum newMode, Texture texture, string tooltip) { OnGUI_ToggleEnum( text, ref currentMode, newMode, texture, tooltip, Style_ToolBarButton_Big); }
|
||||
void OnGUI_ToggleEnumSmall<Enum>( string text, ref Enum currentMode, Enum newMode, Texture texture, string tooltip) { OnGUI_ToggleEnum( text, ref currentMode, newMode, texture, tooltip, EditorStyles.toolbarButton); }
|
||||
void OnGUI_ToggleEnum<Enum>( string text, ref Enum currentMode, Enum newMode, Texture texture, string tooltip, GUIStyle style)
|
||||
{
|
||||
GUI.changed = false;
|
||||
if (GUILayout.Toggle( currentMode.Equals(newMode), new GUIContent(text, texture, tooltip), style, GUILayout.ExpandWidth(true)))
|
||||
{
|
||||
currentMode = newMode;
|
||||
if (GUI.changed)
|
||||
ClearErrors();
|
||||
}
|
||||
}
|
||||
|
||||
int OnGUI_FlagToogle( string Text, string tooltip, int flags, int bit )
|
||||
{
|
||||
bool State = (flags & bit)>0;
|
||||
bool NewState = GUILayout.Toggle(State, new GUIContent(Text, tooltip), "toolbarbutton");
|
||||
if (State!=NewState)
|
||||
{
|
||||
if (!NewState && flags==bit)
|
||||
return flags;
|
||||
|
||||
flags = NewState ? flags | bit : flags & ~bit;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
void OnGUI_SelectableToogleListItem( string Element, ref List<string> Selections, string Style )
|
||||
{
|
||||
bool WasEnabled = Selections.Contains(Element);
|
||||
bool IsEnabled = GUILayout.Toggle( WasEnabled, "", Style, GUILayout.ExpandWidth(false) );
|
||||
|
||||
if (IsEnabled && !WasEnabled)
|
||||
Selections.Add(Element);
|
||||
else
|
||||
if (!IsEnabled && WasEnabled)
|
||||
Selections.Remove(Element);
|
||||
}
|
||||
|
||||
void OnGUI_SelectableToogleListItem( Rect rect, string Element, ref List<string> Selections, string Style )
|
||||
{
|
||||
bool WasEnabled = Selections.Contains(Element);
|
||||
bool IsEnabled = GUI.Toggle( rect, WasEnabled, "", Style );
|
||||
|
||||
if (IsEnabled && !WasEnabled)
|
||||
Selections.Add(Element);
|
||||
else
|
||||
if (!IsEnabled && WasEnabled)
|
||||
Selections.Remove(Element);
|
||||
}
|
||||
|
||||
static bool InTestAction( eTest_ActionType testType )
|
||||
{
|
||||
return mTestAction == testType && UnityEngine.Event.current.type == EventType.Repaint;
|
||||
}
|
||||
static bool TestButton(eTest_ActionType action, string text, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
return GUILayout.Button(text, style, options) || mTestAction == action && UnityEngine.Event.current.type == EventType.Repaint;
|
||||
}
|
||||
|
||||
static bool TestButtonArg(eTest_ActionType action, object arg, string text, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
return GUILayout.Button(text, style, options) || mTestAction == action && (mTestActionArg==null || mTestActionArg.Equals(arg)) && UnityEngine.Event.current.type == EventType.Repaint;
|
||||
}
|
||||
|
||||
|
||||
static bool TestButton(eTest_ActionType action, GUIContent text, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
return GUILayout.Button(text, style, options) || mTestAction == action && UnityEngine.Event.current.type == EventType.Repaint;
|
||||
}
|
||||
|
||||
static bool TestButtonArg(eTest_ActionType action, object arg, GUIContent text, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
return GUILayout.Button(text, style, options) || mTestAction == action && (mTestActionArg == null || mTestActionArg.Equals(arg)) && UnityEngine.Event.current.type == EventType.Repaint;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Error Management
|
||||
|
||||
static void OnGUI_ShowMsg()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(mLocalizationMsg))
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUILayout.HelpBox(mLocalizationMsg, mLocalizationMessageType);
|
||||
|
||||
GUILayout.Space(-5);
|
||||
GUILayout.BeginVertical(GUILayout.Width(15), GUILayout.ExpandHeight(false));
|
||||
GUILayout.Space(15);
|
||||
if (GUILayout.Button("X", GUITools.Style_ToolbarSearchCancelButton, GUILayout.ExpandWidth(false)))
|
||||
ClearErrors();
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(8);
|
||||
}
|
||||
}
|
||||
|
||||
static void ShowError ( string Error, bool ShowInConsole = true ) { ShowMessage ( Error, MessageType.Error, ShowInConsole ); }
|
||||
static void ShowInfo ( string Msg, bool ShowInConsole = false ) { ShowMessage ( Msg, MessageType.Info, ShowInConsole ); }
|
||||
static void ShowWarning( string Msg, bool ShowInConsole = true) { ShowMessage ( Msg, MessageType.Warning, ShowInConsole ); }
|
||||
|
||||
static void ShowMessage( string Msg, MessageType msgType, bool ShowInConsole )
|
||||
{
|
||||
if (string.IsNullOrEmpty(Msg))
|
||||
Msg = string.Empty;
|
||||
|
||||
mLocalizationMsg = Msg;
|
||||
mLocalizationMessageType = msgType;
|
||||
if (ShowInConsole)
|
||||
{
|
||||
switch (msgType)
|
||||
{
|
||||
case MessageType.Error : Debug.LogError(Msg); break;
|
||||
case MessageType.Warning : Debug.LogWarning(Msg); break;
|
||||
default : Debug.Log(Msg); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void ClearErrors()
|
||||
{
|
||||
GUI.FocusControl(null);
|
||||
|
||||
mLocalizationMsg = string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity Version branching
|
||||
|
||||
public static string Editor_GetCurrentScene()
|
||||
{
|
||||
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
|
||||
return EditorApplication.currentScene;
|
||||
#else
|
||||
return SceneManager.GetActiveScene().path;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Editor_MarkSceneDirty()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
|
||||
#else
|
||||
EditorApplication.MarkSceneDirty();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Editor_SaveScene(bool force=false)
|
||||
{
|
||||
if (force)
|
||||
Editor_MarkSceneDirty();
|
||||
|
||||
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
|
||||
EditorApplication.SaveScene ();
|
||||
#else
|
||||
EditorSceneManager.SaveOpenScenes();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Editor_OpenScene( string sceneName )
|
||||
{
|
||||
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
|
||||
if (string.IsNullOrEmpty(sceneName))
|
||||
EditorApplication.NewEmptyScene();
|
||||
else
|
||||
EditorApplication.OpenScene(sceneName);
|
||||
#else
|
||||
if (string.IsNullOrEmpty(sceneName))
|
||||
EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
|
||||
else
|
||||
EditorSceneManager.OpenScene(sceneName);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffd53aaaf6936407d8b087583b0626e9
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,477 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
private List<string> mTranslationTerms = new List<string>();
|
||||
private Dictionary<string, TranslationQuery> mTranslationRequests = new Dictionary<string, TranslationQuery> ();
|
||||
private bool mAppNameTerm_Expanded;
|
||||
|
||||
private List<string> mLanguageCodePopupList;
|
||||
|
||||
#endregion
|
||||
|
||||
void OnGUI_Languages()
|
||||
{
|
||||
//GUILayout.Space(5);
|
||||
|
||||
OnGUI_ShowMsg();
|
||||
|
||||
OnGUI_LanguageList();
|
||||
|
||||
OnGUI_StoreIntegration();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label(new GUIContent("On Missing Translation:", "What should happen IN-GAME when a term is not yet translated to the current language?"), EditorStyles.boldLabel, GUILayout.Width(200));
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Space(7);
|
||||
EditorGUILayout.PropertyField(mProp_OnMissingTranslation, GUITools.EmptyContent, GUILayout.Width(165));
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label(new GUIContent("Unload Languages At Runtime:", "When playing the game, the plugin will unload all unused languages and only load them when needed"), EditorStyles.boldLabel, GUILayout.Width(200));
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Space(7);
|
||||
EditorGUILayout.PropertyField(mProp_AllowUnloadingLanguages, GUITools.EmptyContent, GUILayout.Width(165));
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
||||
|
||||
|
||||
string firstLanguage = "";
|
||||
if (mLanguageSource.mLanguages.Count > 0)
|
||||
firstLanguage = " (" + mLanguageSource.mLanguages [0].Name + ")";
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label(new GUIContent("Default Language:", "When the game starts this is the language that will be used until the player manually selects a language"), EditorStyles.boldLabel, GUILayout.Width(160));
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Space(7);
|
||||
|
||||
mProp_IgnoreDeviceLanguage.boolValue = EditorGUILayout.Popup(mProp_IgnoreDeviceLanguage.boolValue?1:0, new[]{"Device Language", "First in List"+firstLanguage}, GUILayout.ExpandWidth(true))==1;
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
#region GUI Languages
|
||||
|
||||
void OnGUI_LanguageList()
|
||||
{
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label ("Languages:", EditorStyles.miniLabel, GUILayout.ExpandWidth(false));
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label ("Code:", EditorStyles.miniLabel);
|
||||
GUILayout.Space(170);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
//--[ Language List ]--------------------------
|
||||
|
||||
int IndexLanguageToDelete = -1;
|
||||
int LanguageToMoveUp = -1;
|
||||
int LanguageToMoveDown = -1;
|
||||
GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
|
||||
mScrollPos_Languages = GUILayout.BeginScrollView( mScrollPos_Languages, LocalizeInspector.GUIStyle_OldTextArea, GUILayout.MinHeight (200), /*GUILayout.MaxHeight(Screen.height),*/ GUILayout.ExpandHeight(false));
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
if (mLanguageCodePopupList == null || mLanguageCodePopupList.Count==0)
|
||||
{
|
||||
mLanguageCodePopupList = GoogleLanguages.GetLanguagesForDropdown("", "");
|
||||
mLanguageCodePopupList.Sort();
|
||||
mLanguageCodePopupList.Insert(0, string.Empty);
|
||||
}
|
||||
|
||||
for (int i=0, imax=mProp_Languages.arraySize; i<imax; ++i)
|
||||
{
|
||||
SerializedProperty Prop_Lang = mProp_Languages.GetArrayElementAtIndex(i);
|
||||
SerializedProperty Prop_LangName = Prop_Lang.FindPropertyRelative("Name");
|
||||
SerializedProperty Prop_LangCode = Prop_Lang.FindPropertyRelative("Code");
|
||||
SerializedProperty Prop_Flags = Prop_Lang.FindPropertyRelative("Flags");
|
||||
bool isLanguageEnabled = (Prop_Flags.intValue & (int)eLanguageDataFlags.DISABLED)==0;
|
||||
|
||||
GUI.color = isLanguageEnabled ? Color.white : new Color(1, 1, 1, 0.3f);
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
if (GUILayout.Button ("X", "toolbarbutton", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
IndexLanguageToDelete = i;
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
string LanName = EditorGUILayout.TextField(Prop_LangName.stringValue, GUILayout.ExpandWidth(true));
|
||||
if (EditorGUI.EndChangeCheck() && !string.IsNullOrEmpty(LanName))
|
||||
{
|
||||
Prop_LangName.stringValue = LanName;
|
||||
}
|
||||
|
||||
var currentCode = "[" + Prop_LangCode.stringValue + "]";
|
||||
|
||||
if (isLanguageEnabled)
|
||||
{
|
||||
int Index = Mathf.Max(0, mLanguageCodePopupList.FindIndex(c => c.Contains(currentCode)));
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Index = EditorGUILayout.Popup(Index, mLanguageCodePopupList.ToArray(), EditorStyles.toolbarPopup, GUILayout.Width(60));
|
||||
if (EditorGUI.EndChangeCheck() && Index >= 0)
|
||||
{
|
||||
currentCode = mLanguageCodePopupList[Index];
|
||||
int i0 = currentCode.IndexOf("[");
|
||||
int i1 = currentCode.IndexOf("]");
|
||||
if (i0 >= 0 && i1 > i0)
|
||||
Prop_LangCode.stringValue = currentCode.Substring(i0 + 1, i1 - i0 - 1);
|
||||
else
|
||||
Prop_LangCode.stringValue = string.Empty;
|
||||
}
|
||||
var rect = GUILayoutUtility.GetLastRect();
|
||||
GUI.Label(rect, Prop_LangCode.stringValue, EditorStyles.toolbarPopup);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label(Prop_LangCode.stringValue, EditorStyles.toolbarPopup, GUILayout.Width(60));
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUI.enabled = i<imax-1;
|
||||
if (GUILayout.Button( "\u25BC", EditorStyles.toolbarButton, GUILayout.Width(18))) LanguageToMoveDown = i;
|
||||
GUI.enabled = i>0;
|
||||
if (GUILayout.Button( "\u25B2", EditorStyles.toolbarButton, GUILayout.Width(18))) LanguageToMoveUp = i;
|
||||
|
||||
GUI.enabled = true;
|
||||
if (GUILayout.Button( new GUIContent("Show", "Preview all localizations into this language"), EditorStyles.toolbarButton, GUILayout.Width(35)))
|
||||
{
|
||||
LocalizationManager.SetLanguageAndCode( LanName, Prop_LangCode.stringValue, false, true);
|
||||
}
|
||||
|
||||
if (TestButtonArg( eTest_ActionType.Button_Languages_TranslateAll, i, new GUIContent("Translate", "Translate all empty terms"), EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
GUITools.DelayedCall( () => TranslateAllToLanguage(LanName));
|
||||
}
|
||||
GUI.enabled = true;
|
||||
GUI.color = Color.white;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
isLanguageEnabled = EditorGUILayout.Toggle(isLanguageEnabled, GUILayout.Width(15));
|
||||
|
||||
var r = GUILayoutUtility.GetLastRect();
|
||||
GUI.Label(r, new GUIContent("", "Enable/Disable the language.\nDisabled languages can be used to store data values or to avoid showing Languages that are stil under development"));
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Prop_Flags.intValue = (Prop_Flags.intValue & ~(int)eLanguageDataFlags.DISABLED) | (isLanguageEnabled ? 0 : (int)eLanguageDataFlags.DISABLED);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
|
||||
OnGUI_AddLanguage( mProp_Languages );
|
||||
|
||||
if (mConnection_WWW!=null || mConnection_Text.Contains("Translating"))
|
||||
{
|
||||
// Connection Status Bar
|
||||
int time = (int)(Time.realtimeSinceStartup % 2 * 2.5);
|
||||
string Loading = mConnection_Text + ".....".Substring(0, time);
|
||||
GUI.color = Color.gray;
|
||||
GUILayout.BeginHorizontal(LocalizeInspector.GUIStyle_OldTextArea);
|
||||
GUILayout.Label (Loading, EditorStyles.miniLabel);
|
||||
GUI.color = Color.white;
|
||||
if (GUILayout.Button("Cancel", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
GoogleTranslation.CancelCurrentGoogleTranslations ();
|
||||
StopConnectionWWW();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
if (IndexLanguageToDelete>=0)
|
||||
{
|
||||
if (EditorUtility.DisplayDialog ("Confirm delete", "Are you sure you want to delete the selected language", "Yes", "Cancel"))
|
||||
{
|
||||
mLanguageSource.RemoveLanguage (mLanguageSource.mLanguages [IndexLanguageToDelete].Name);
|
||||
serializedObject.Update ();
|
||||
ParseTerms (true, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (LanguageToMoveUp>=0) SwapLanguages( LanguageToMoveUp, LanguageToMoveUp-1 );
|
||||
if (LanguageToMoveDown>=0) SwapLanguages( LanguageToMoveDown, LanguageToMoveDown+1 );
|
||||
}
|
||||
|
||||
void SwapLanguages( int iFirst, int iSecond )
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
LanguageSourceData Source = mLanguageSource;
|
||||
|
||||
SwapValues( Source.mLanguages, iFirst, iSecond );
|
||||
foreach (TermData termData in Source.mTerms)
|
||||
{
|
||||
SwapValues ( termData.Languages, iFirst, iSecond );
|
||||
SwapValues ( termData.Flags, iFirst, iSecond );
|
||||
}
|
||||
serializedObject.Update();
|
||||
}
|
||||
|
||||
void SwapValues( List<LanguageData> mList, int Index1, int Index2 )
|
||||
{
|
||||
LanguageData temp = mList[Index1];
|
||||
mList[Index1] = mList[Index2];
|
||||
mList[Index2] = temp;
|
||||
}
|
||||
void SwapValues( string[] mList, int Index1, int Index2 )
|
||||
{
|
||||
string temp = mList[Index1];
|
||||
mList[Index1] = mList[Index2];
|
||||
mList[Index2] = temp;
|
||||
}
|
||||
void SwapValues( byte[] mList, int Index1, int Index2 )
|
||||
{
|
||||
byte temp = mList[Index1];
|
||||
mList[Index1] = mList[Index2];
|
||||
mList[Index2] = temp;
|
||||
}
|
||||
|
||||
|
||||
void OnGUI_AddLanguage( SerializedProperty Prop_Languages)
|
||||
{
|
||||
//--[ Add Language Upper Toolbar ]-----------------
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
mLanguages_NewLanguage = EditorGUILayout.TextField("", mLanguages_NewLanguage, EditorStyles.toolbarTextField, GUILayout.ExpandWidth(true));
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUI.enabled = !string.IsNullOrEmpty (mLanguages_NewLanguage);
|
||||
if (TestButton(eTest_ActionType.Button_AddLanguageManual,"Add", EditorStyles.toolbarButton, GUILayout.Width(50)))
|
||||
{
|
||||
Prop_Languages.serializedObject.ApplyModifiedProperties();
|
||||
mLanguageSource.AddLanguage( mLanguages_NewLanguage, GoogleLanguages.GetLanguageCode(mLanguages_NewLanguage) );
|
||||
Prop_Languages.serializedObject.Update();
|
||||
mLanguages_NewLanguage = "";
|
||||
GUI.FocusControl(string.Empty);
|
||||
}
|
||||
GUI.enabled = true;
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
||||
//--[ Add Language Bottom Toolbar ]-----------------
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
//-- Language Dropdown -----------------
|
||||
string CodesToExclude = string.Empty;
|
||||
foreach (var LanData in mLanguageSource.mLanguages)
|
||||
CodesToExclude = string.Concat(CodesToExclude, "[", LanData.Code, "]");
|
||||
|
||||
List<string> Languages = GoogleLanguages.GetLanguagesForDropdown(mLanguages_NewLanguage, CodesToExclude);
|
||||
|
||||
GUI.changed = false;
|
||||
int index = EditorGUILayout.Popup(0, Languages.ToArray(), EditorStyles.toolbarDropDown);
|
||||
|
||||
if (GUI.changed && index>=0)
|
||||
{
|
||||
mLanguages_NewLanguage = GoogleLanguages.GetFormatedLanguageName( Languages[index] );
|
||||
}
|
||||
|
||||
|
||||
if (TestButton(eTest_ActionType.Button_AddLanguageFromPopup, "Add", EditorStyles.toolbarButton, GUILayout.Width(50)) && index>=0)
|
||||
{
|
||||
Prop_Languages.serializedObject.ApplyModifiedProperties();
|
||||
mLanguages_NewLanguage = GoogleLanguages.GetFormatedLanguageName(Languages[index]);
|
||||
|
||||
if (!string.IsNullOrEmpty(mLanguages_NewLanguage))
|
||||
mLanguageSource.AddLanguage(mLanguages_NewLanguage, GoogleLanguages.GetLanguageCode(mLanguages_NewLanguage));
|
||||
Prop_Languages.serializedObject.Update();
|
||||
|
||||
mLanguages_NewLanguage = "";
|
||||
GUI.FocusControl(string.Empty);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
|
||||
|
||||
void TranslateAllToLanguage (string lanName)
|
||||
{
|
||||
if (!GoogleTranslation.CanTranslate ())
|
||||
{
|
||||
ShowError ("WebService is not set correctly or needs to be reinstalled");
|
||||
return;
|
||||
}
|
||||
ClearErrors();
|
||||
int LanIndex = mLanguageSource.GetLanguageIndex (lanName);
|
||||
string code = mLanguageSource.mLanguages [LanIndex].Code;
|
||||
string googleCode = GoogleLanguages.GetGoogleLanguageCode(code);
|
||||
if (string.IsNullOrEmpty(googleCode))
|
||||
{
|
||||
ShowError("Language '" + code + "' is not supported by google translate");
|
||||
return;
|
||||
}
|
||||
googleCode = code;
|
||||
|
||||
mTranslationTerms.Clear ();
|
||||
mTranslationRequests.Clear ();
|
||||
foreach (var termData in mLanguageSource.mTerms)
|
||||
{
|
||||
if (termData.TermType != eTermType.Text)
|
||||
continue;
|
||||
|
||||
if (!string.IsNullOrEmpty(termData.Languages[LanIndex]))
|
||||
continue;
|
||||
|
||||
string sourceCode, sourceText;
|
||||
FindTranslationSource( LanguageSourceData.GetKeyFromFullTerm(termData.Term), termData, code, null, out sourceText, out sourceCode );
|
||||
|
||||
mTranslationTerms.Add (termData.Term);
|
||||
|
||||
GoogleTranslation.CreateQueries(sourceText, sourceCode, googleCode, mTranslationRequests); // can split plurals into several queries
|
||||
}
|
||||
|
||||
if (mTranslationRequests.Count == 0)
|
||||
{
|
||||
StopConnectionWWW ();
|
||||
return;
|
||||
}
|
||||
|
||||
mConnection_WWW = null;
|
||||
mConnection_Text = "Translating"; if (mTranslationRequests.Count > 1) mConnection_Text += " (" + mTranslationRequests.Count + ")";
|
||||
mConnection_Callback = null;
|
||||
//EditorApplication.update += CheckForConnection;
|
||||
|
||||
GoogleTranslation.Translate (mTranslationRequests, OnLanguageTranslated);
|
||||
}
|
||||
|
||||
void OnLanguageTranslated( Dictionary<string, TranslationQuery> requests, string Error )
|
||||
{
|
||||
//Debug.Log (Result);
|
||||
|
||||
//if (Result.Contains("Service invoked too many times"))
|
||||
//{
|
||||
// TimeStartTranslation = EditorApplication.timeSinceStartup + 1;
|
||||
// EditorApplication.update += DelayedStartTranslation;
|
||||
// mConnection_Text = "Translating (" + mTranslationRequests.Count + ")";
|
||||
// return;
|
||||
//}
|
||||
|
||||
//if (!string.IsNullOrEmpty(Error))/* || !Result.Contains("<i2>")*/
|
||||
//{
|
||||
// Debug.LogError("WEB ERROR: " + Error);
|
||||
// ShowError ("Unable to access Google or not valid request");
|
||||
// return;
|
||||
//}
|
||||
|
||||
ClearErrors();
|
||||
StopConnectionWWW();
|
||||
|
||||
if (!string.IsNullOrEmpty(Error))
|
||||
{
|
||||
ShowError (Error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (requests.Values.Count == 0)
|
||||
return;
|
||||
|
||||
var langCode = requests.Values.First().TargetLanguagesCode [0];
|
||||
//langCode = GoogleLanguages.GetGoogleLanguageCode(langCode);
|
||||
int langIndex = mLanguageSource.GetLanguageIndexFromCode (langCode, false);
|
||||
//if (langIndex >= 0)
|
||||
{
|
||||
foreach (var term in mTranslationTerms)
|
||||
{
|
||||
var termData = mLanguageSource.GetTermData(term);
|
||||
if (termData == null)
|
||||
continue;
|
||||
if (termData.TermType != eTermType.Text)
|
||||
continue;
|
||||
//if (termData.Languages.Length <= langIndex)
|
||||
// continue;
|
||||
|
||||
string sourceCode, sourceText;
|
||||
FindTranslationSource(LanguageSourceData.GetKeyFromFullTerm(termData.Term), termData, langCode, null, out sourceText, out sourceCode);
|
||||
|
||||
string result = GoogleTranslation.RebuildTranslation(sourceText, mTranslationRequests, langCode); // gets the result from google and rebuilds the text from multiple queries if its is plurals
|
||||
|
||||
termData.Languages[langIndex] = result;
|
||||
}
|
||||
}
|
||||
|
||||
mTranslationTerms.Clear ();
|
||||
mTranslationRequests.Clear ();
|
||||
StopConnectionWWW ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Store Integration
|
||||
|
||||
void OnGUI_StoreIntegration()
|
||||
{
|
||||
GUIStyle lstyle = new GUIStyle (EditorStyles.label);
|
||||
lstyle.richText = true;
|
||||
|
||||
GUILayout.BeginHorizontal ();
|
||||
GUILayout.Label (new GUIContent("Store Integration:", "Setups the stores to detect that the game has localization, Android adds strings.xml for each language. IOS modifies the Info.plist"), EditorStyles.boldLabel, GUILayout.Width(160));
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUILayout.Label( new GUIContent( "<color=green><size=16>\u2713</size></color> IOS", "Setups the stores to show in iTunes and the Appstore all the languages that this app supports, also localizes the app name if available" ), lstyle, GUILayout.Width( 90 ) );
|
||||
GUILayout.Label( new GUIContent( "<color=green><size=16>\u2713</size></color> Android", "Setups the stores to show in GooglePlay all the languages this app supports, also localizes the app name if available" ), lstyle, GUILayout.Width( 90 ) );
|
||||
GUILayout.EndHorizontal ();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
mAppNameTerm_Expanded = GUILayout.Toggle(mAppNameTerm_Expanded, new GUIContent( "App Name translations:", "How should the game be named in the devices based on their language" ), EditorStyles.foldout, GUILayout.Width( 160 ) );
|
||||
|
||||
GUILayout.Label("", GUILayout.ExpandWidth(true));
|
||||
var rect = GUILayoutUtility.GetLastRect();
|
||||
TermsPopup_Drawer.ShowGUI( rect, mProp_AppNameTerm, GUITools.EmptyContent, mLanguageSource);
|
||||
|
||||
if (GUILayout.Button("New Term", EditorStyles.miniButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
AddLocalTerm("App_Name");
|
||||
mProp_AppNameTerm.stringValue = "App_Name";
|
||||
mAppNameTerm_Expanded = true;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (mAppNameTerm_Expanded)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(10);
|
||||
|
||||
GUILayout.BeginVertical("Box");
|
||||
var termName = mProp_AppNameTerm.stringValue;
|
||||
if (!string.IsNullOrEmpty(termName))
|
||||
{
|
||||
var termData = LocalizationManager.GetTermData(termName);
|
||||
if (termData != null)
|
||||
OnGUI_Keys_Languages(mProp_AppNameTerm.stringValue, ref termData, null, true, mLanguageSource);
|
||||
}
|
||||
GUILayout.Space(10);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("<b>Default App Name:</b>", lstyle, GUITools.DontExpandWidth);
|
||||
GUILayout.Label(Application.productName);
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 304783c1e95d94a598aecd17728c8556
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,727 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using TEngine.Localization.SimpleJSON;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
|
||||
public static Dictionary<string, string> mGoogleSpreadsheets = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
|
||||
public UnityWebRequest mConnection_WWW;
|
||||
|
||||
delegate void fnConnectionCallback(string Result, string Error);
|
||||
event fnConnectionCallback mConnection_Callback;
|
||||
//float mConnection_TimeOut;
|
||||
|
||||
string mConnection_Text = string.Empty;
|
||||
|
||||
string mWebService_Status;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI
|
||||
|
||||
void OnGUI_Spreadsheet_Google()
|
||||
{
|
||||
GUILayout.Space(20);
|
||||
|
||||
#if UNITY_WEBPLAYER
|
||||
mConnection_Text = string.Empty;
|
||||
EditorGUILayout.HelpBox("Google Synchronization is not supported when in WebPlayer mode." + mConnection_Text, MessageType.Info);
|
||||
|
||||
mProp_GoogleUpdateFrequency.enumValueIndex = mProp_GoogleUpdateFrequency.enumValueIndex; // to avoid the warning "unused"
|
||||
mProp_GoogleUpdateSynchronization.enumValueIndex = mProp_GoogleUpdateSynchronization.enumValueIndex;
|
||||
#else
|
||||
|
||||
OnGUI_GoogleCredentials();
|
||||
|
||||
OnGUI_ShowMsg();
|
||||
|
||||
if (string.IsNullOrEmpty(mProp_Google_WebServiceURL.stringValue))
|
||||
return;
|
||||
|
||||
if (mWebService_Status == "Offline")
|
||||
return;
|
||||
|
||||
GUILayout.Space(20);
|
||||
|
||||
GUI.backgroundColor = Color.Lerp(Color.gray, Color.white, 0.5f);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height (1));
|
||||
GUI.backgroundColor = Color.white;
|
||||
GUILayout.Space(10);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label(new GUIContent(" Password", "This should match the value of the LocalizationPassword variable in the WebService Script in your Google Drive"), GUILayout.Width(108));
|
||||
mProp_Google_Password.stringValue = EditorGUILayout.TextField(mProp_Google_Password.stringValue, GUILayout.ExpandWidth(true));
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
OnGUI_GoogleSpreadsheetsInGDrive();
|
||||
GUILayout.EndVertical();
|
||||
|
||||
if (mConnection_WWW!=null)
|
||||
{
|
||||
// Connection Status Bar
|
||||
int time = (int)(Time.realtimeSinceStartup % 2 * 2.5);
|
||||
string Loading = mConnection_Text + ".....".Substring(0, time);
|
||||
GUI.color = Color.gray;
|
||||
GUILayout.BeginHorizontal(LocalizeInspector.GUIStyle_OldTextArea);
|
||||
GUILayout.Label (Loading, EditorStyles.miniLabel);
|
||||
GUI.color = Color.white;
|
||||
if (GUILayout.Button("Cancel", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
StopConnectionWWW();
|
||||
GUILayout.EndHorizontal();
|
||||
Repaint();
|
||||
}
|
||||
//else
|
||||
// GUILayout.Space(10);
|
||||
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
GUILayout.Space(5);
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
LanguageSourceData.eGoogleUpdateFrequency GoogleUpdateFrequency = (LanguageSourceData.eGoogleUpdateFrequency)mProp_GoogleUpdateFrequency.enumValueIndex;
|
||||
GoogleUpdateFrequency = (LanguageSourceData.eGoogleUpdateFrequency)EditorGUILayout.EnumPopup("Auto Update Frequency", GoogleUpdateFrequency, GUILayout.ExpandWidth(true));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
mProp_GoogleUpdateFrequency.enumValueIndex = (int)GoogleUpdateFrequency;
|
||||
}
|
||||
|
||||
GUILayout.Space(10);
|
||||
GUILayout.Label("Delay:");
|
||||
mProp_GoogleUpdateDelay.floatValue = EditorGUILayout.FloatField(mProp_GoogleUpdateDelay.floatValue, GUILayout.Width(30));
|
||||
GUILayout.Label("secs");
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
var GoogleInEditorCheckFrequency = (LanguageSourceData.eGoogleUpdateFrequency)mProp_GoogleInEditorCheckFrequency.enumValueIndex;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
GoogleInEditorCheckFrequency = (LanguageSourceData.eGoogleUpdateFrequency)EditorGUILayout.EnumPopup(new GUIContent("In-Editor Check Frequency", "How often the editor will verify that the Spreadsheet is up-to-date with the LanguageSource. Having un-synchronized Spreadsheets can lead to issues when playing in the device as the download data will override the one in the build"), GoogleInEditorCheckFrequency, GUILayout.ExpandWidth(false));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
mProp_GoogleInEditorCheckFrequency.enumValueIndex = (int)GoogleInEditorCheckFrequency;
|
||||
}
|
||||
GUILayout.Space(122);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label("Update Synchronization", GUILayout.Width(180));
|
||||
EditorGUI.BeginChangeCheck();
|
||||
LanguageSourceData.eGoogleUpdateSynchronization GoogleUpdateSynchronization = (LanguageSourceData.eGoogleUpdateSynchronization)mProp_GoogleUpdateSynchronization.enumValueIndex;
|
||||
GoogleUpdateSynchronization = (LanguageSourceData.eGoogleUpdateSynchronization)EditorGUILayout.EnumPopup(GoogleUpdateSynchronization, GUILayout.Width(178));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
mProp_GoogleUpdateSynchronization.enumValueIndex = (int)GoogleUpdateSynchronization;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(5);
|
||||
|
||||
GUI.changed = false;
|
||||
bool OpenDataSourceAfterExport = EditorPrefs.GetBool("I2Loc OpenDataSourceAfterExport", true);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
OpenDataSourceAfterExport = GUILayout.Toggle(OpenDataSourceAfterExport, "Open Spreadsheet after Export");
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
GUI.changed = false;
|
||||
EditorPrefs.SetBool("I2Loc OpenDataSourceAfterExport", OpenDataSourceAfterExport);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
GUILayout.Space(5);
|
||||
}
|
||||
|
||||
void OnGUI_GoogleCredentials()
|
||||
{
|
||||
GUI.enabled = mConnection_WWW==null;
|
||||
|
||||
GUI.changed = false;
|
||||
|
||||
string WebServiceHelp = "The web service is a script running on the google drive where the spreadsheet you want to use is located.\nThat script allows the game to synchronize the localization even after the game is published.";
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label (new GUIContent("Web Service URL:", WebServiceHelp), GUILayout.Width(110));
|
||||
|
||||
GUI.SetNextControlName ("WebServiceURL");
|
||||
mProp_Google_WebServiceURL.stringValue = EditorGUILayout.TextField(mProp_Google_WebServiceURL.stringValue);
|
||||
|
||||
if (!string.IsNullOrEmpty(mWebService_Status))
|
||||
{
|
||||
if (mWebService_Status=="Online")
|
||||
{
|
||||
GUI.color = Color.green;
|
||||
GUILayout.Label( "", GUILayout.Width(17));
|
||||
Rect r = GUILayoutUtility.GetLastRect(); r.xMin += 3; r.yMin-= 3; r.xMax+= 2; r.yMax+=2;
|
||||
GUI.Label( r, new GUIContent("\u2713", "Online"), EditorStyles.whiteLargeLabel);
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
else
|
||||
if (mWebService_Status=="Offline")
|
||||
{
|
||||
GUI.color = Color.red;
|
||||
GUILayout.Label( "", GUILayout.Width(17));
|
||||
Rect r = GUILayoutUtility.GetLastRect(); r.xMin += 3; r.yMin-= 3; r.xMax+= 2; r.yMax+=2;
|
||||
GUI.Label( r, new GUIContent("\u2717", mWebService_Status), EditorStyles.whiteLargeLabel);
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
else
|
||||
if (mWebService_Status=="UnsupportedVersion")
|
||||
{
|
||||
Rect rect = GUILayoutUtility.GetLastRect();
|
||||
float Width = 15;
|
||||
rect.xMin = rect.xMax+1;
|
||||
rect.xMax = rect.xMin + rect.height;
|
||||
GUITools.DrawSkinIcon(rect, "CN EntryWarnIcon", "CN EntryWarn");
|
||||
GUI.Label(rect, new GUIContent("\u2717", "The current Google WebService is not supported.\nPlease, delete the WebService from the Google Drive and Install the latest version."));
|
||||
GUILayout.Space (Width);
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space (118);
|
||||
if (GUILayout.Button(new GUIContent("Install", "This opens the Web Service Script and shows you steps to install and authorize it on your Google Drive"), EditorStyles.toolbarButton))
|
||||
{
|
||||
ClearErrors();
|
||||
Application.OpenURL("https://script.google.com/d/1zcsLSmq3Oddd8AsLuoKNDG1Y0eYBOHzyvGT7v94u1oN6igmsZb_PJzEm/newcopy"); // V5
|
||||
//Application.OpenURL("https://goo.gl/RBCO0o"); // V4:https://script.google.com/d/1T7e5_40NcgRyind-yeg4PAkHz9TNZJ22F4RcbOvCpAs03JNf1vKNNTZB/newcopy
|
||||
//Application.OpenURL("https://goo.gl/wFSbv2");// V3:https://script.google.com/d/1CxQDSXflsXRaH3M7xGfrIDrFwOIHWPsYTWi4mRZ_k77nyIInTgIk63Kd/newcopy");
|
||||
}
|
||||
if (GUILayout.Button("Verify", EditorStyles.toolbarButton))
|
||||
{
|
||||
ClearErrors();
|
||||
VerifyGoogleService(mProp_Google_WebServiceURL.stringValue);
|
||||
GUI.changed = false;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(mProp_Google_WebServiceURL.stringValue))
|
||||
{
|
||||
EditorGUILayout.HelpBox(WebServiceHelp, MessageType.Info);
|
||||
}
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
if (string.IsNullOrEmpty(mProp_Google_WebServiceURL.stringValue))
|
||||
{
|
||||
mProp_Google_SpreadsheetKey.stringValue = string.Empty;
|
||||
mProp_Google_SpreadsheetName.stringValue = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
// If the web service changed then clear the cached spreadsheet keys
|
||||
mGoogleSpreadsheets.Clear();
|
||||
|
||||
GUI.changed = false;
|
||||
ClearErrors();
|
||||
}
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
void OnGUI_GoogleSpreadsheetsInGDrive()
|
||||
{
|
||||
GUI.enabled = mConnection_WWW==null;
|
||||
|
||||
string[] Spreadsheets;
|
||||
string[] SpreadsheetsKey;
|
||||
if (mGoogleSpreadsheets.Count>0 || string.IsNullOrEmpty(mProp_Google_SpreadsheetKey.stringValue))
|
||||
{
|
||||
Spreadsheets = new List<string>(mGoogleSpreadsheets.Keys).ToArray();
|
||||
SpreadsheetsKey = new List<string>(mGoogleSpreadsheets.Values).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
Spreadsheets = new[]{mProp_Google_SpreadsheetName.stringValue ?? string.Empty};
|
||||
SpreadsheetsKey = new[]{mProp_Google_SpreadsheetKey.stringValue ?? string.Empty};
|
||||
}
|
||||
int mSpreadsheetIndex = Array.IndexOf(SpreadsheetsKey, mProp_Google_SpreadsheetKey.stringValue);
|
||||
|
||||
//--[ Spreadsheets ]------------------
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(10);
|
||||
GUILayout.Label ("In Google Drive:", GUILayout.Width(100));
|
||||
|
||||
GUI.changed = false;
|
||||
GUI.enabled = Spreadsheets != null && Spreadsheets.Length>0;
|
||||
mSpreadsheetIndex = EditorGUILayout.Popup(mSpreadsheetIndex, Spreadsheets, EditorStyles.toolbarPopup);
|
||||
if (GUI.changed && mSpreadsheetIndex >= 0)
|
||||
{
|
||||
mProp_Google_SpreadsheetKey.stringValue = SpreadsheetsKey[mSpreadsheetIndex];
|
||||
mProp_Google_SpreadsheetName.stringValue = Spreadsheets[mSpreadsheetIndex];
|
||||
GUI.changed = false;
|
||||
}
|
||||
GUI.enabled = true;
|
||||
|
||||
GUI.enabled = !string.IsNullOrEmpty(mProp_Google_SpreadsheetKey.stringValue) && mConnection_WWW==null;
|
||||
if (GUILayout.Button("X", EditorStyles.toolbarButton,GUILayout.ExpandWidth(false)))
|
||||
mProp_Google_SpreadsheetKey.stringValue = string.Empty;
|
||||
GUI.enabled = true;
|
||||
GUILayout.Space(10);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(2);
|
||||
|
||||
//--[ Spreadsheets Operations ]------------------
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(114);
|
||||
if (GUILayout.Button("New", EditorStyles.toolbarButton,GUILayout.ExpandWidth(true)))
|
||||
Google_NewSpreadsheet();
|
||||
|
||||
GUI.enabled = !string.IsNullOrEmpty(mProp_Google_SpreadsheetKey.stringValue) && mConnection_WWW==null;
|
||||
if (GUILayout.Button("Open", EditorStyles.toolbarButton,GUILayout.ExpandWidth(true)))
|
||||
OpenGoogleSpreadsheet(mProp_Google_SpreadsheetKey.stringValue);
|
||||
GUI.enabled = mConnection_WWW==null;
|
||||
|
||||
GUILayout.Space(5);
|
||||
|
||||
if (TestButton(eTest_ActionType.Button_GoogleSpreadsheet_RefreshList, "Refresh", EditorStyles.toolbarButton,GUILayout.ExpandWidth(true)))
|
||||
EditorApplication.update+=Google_FindSpreadsheets;
|
||||
|
||||
GUILayout.Space(10);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(15);
|
||||
|
||||
if (!string.IsNullOrEmpty(mProp_Google_SpreadsheetKey.stringValue))
|
||||
OnGUI_GoogleButtons_ImportExport( mProp_Google_SpreadsheetKey.stringValue );
|
||||
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
|
||||
private void OnGUI_ImportButtons()
|
||||
{
|
||||
eSpreadsheetUpdateMode Mode = SynchronizationButtons("Import");
|
||||
if (Mode != eSpreadsheetUpdateMode.None || InTestAction(eTest_ActionType.Button_GoogleSpreadsheet_Import))
|
||||
{
|
||||
if (mTestAction == eTest_ActionType.Button_GoogleSpreadsheet_Import)
|
||||
Mode = (eSpreadsheetUpdateMode)mTestActionArg;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
var modeCopy = Mode;
|
||||
GUITools.DelayedCall(() => Import_Google(modeCopy));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI_ExportButtons()
|
||||
{
|
||||
eSpreadsheetUpdateMode Mode = SynchronizationButtons("Export");
|
||||
if (Mode != eSpreadsheetUpdateMode.None || InTestAction(eTest_ActionType.Button_GoogleSpreadsheet_Export))
|
||||
{
|
||||
if (mTestAction == eTest_ActionType.Button_GoogleSpreadsheet_Export)
|
||||
Mode = (eSpreadsheetUpdateMode)mTestActionArg;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
var modeCopy = Mode;
|
||||
GUITools.DelayedCall(() => Export_Google(modeCopy));
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_GoogleButtons_ImportExport( string SpreadsheetKey )
|
||||
{
|
||||
GUI.enabled = !string.IsNullOrEmpty(SpreadsheetKey) && mConnection_WWW==null;
|
||||
|
||||
bool vertical = EditorGUIUtility.currentViewWidth < 450;
|
||||
|
||||
if (vertical)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
OnGUI_ImportButtons();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
OnGUI_ExportButtons();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
OnGUI_ImportButtons();
|
||||
GUILayout.FlexibleSpace();
|
||||
OnGUI_ExportButtons();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.BeginVertical();
|
||||
EditorGUIUtility.labelWidth += 10;
|
||||
EditorGUILayout.PropertyField(mProp_Spreadsheet_SpecializationAsRows, new GUIContent("Show Specializations as Rows", "true: Make each specialization a separate row (e.g. Term[VR]..., Term[Touch]....\nfalse: Merge specializations into same cell separated by [i2s_XXX]"));
|
||||
EditorGUILayout.PropertyField(mProp_Spreadsheet_SortRows, new GUIContent("Sort Rows", "true: Sort each term by its name....\nfalse: Keep the terms order"));
|
||||
EditorGUIUtility.labelWidth -= 10;
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(10);
|
||||
|
||||
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
eSpreadsheetUpdateMode SynchronizationButtons( string Operation, bool ForceReplace = false )
|
||||
{
|
||||
eSpreadsheetUpdateMode Result = eSpreadsheetUpdateMode.None;
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Width (1));
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label(Operation, EditorStyles.miniLabel);
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button( "Replace", EditorStyles.toolbarButton, GUILayout.Width(60)))
|
||||
Result = eSpreadsheetUpdateMode.Replace;
|
||||
|
||||
if (ForceReplace) GUI.enabled = false;
|
||||
if (GUILayout.Button( "Merge", EditorStyles.toolbarButton, GUILayout.Width(60)))
|
||||
Result = eSpreadsheetUpdateMode.Merge;
|
||||
|
||||
if (GUILayout.Button( "Add New", EditorStyles.toolbarButton, GUILayout.Width(60)))
|
||||
Result = eSpreadsheetUpdateMode.AddNewTerms;
|
||||
GUI.enabled = mConnection_WWW==null;
|
||||
GUILayout.Space(1);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(2);
|
||||
GUILayout.EndVertical();
|
||||
|
||||
if (Result != eSpreadsheetUpdateMode.None)
|
||||
ClearErrors();
|
||||
|
||||
return Result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
void VerifyGoogleService( string WebServiceURL )
|
||||
{
|
||||
#if UNITY_WEBPLAYER
|
||||
ShowError ("Contacting google translation is not yet supported on WebPlayer" );
|
||||
#else
|
||||
StopConnectionWWW();
|
||||
mWebService_Status = null;
|
||||
mConnection_WWW = UnityWebRequest.Get(WebServiceURL + "?action=Ping");
|
||||
I2Utils.SendWebRequest(mConnection_WWW);
|
||||
mConnection_Callback = OnVerifyGoogleService;
|
||||
EditorApplication.update += CheckForConnection;
|
||||
mConnection_Text = "Verifying Web Service";
|
||||
//mConnection_TimeOut = Time.realtimeSinceStartup + 10;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OnVerifyGoogleService( string Result, string Error )
|
||||
{
|
||||
if (Result.Contains("Authorization is required to perform that action"))
|
||||
{
|
||||
ShowWarning("You need to authorize the webservice before using it. Check the steps 4 and 5 in the WebService Script");
|
||||
mWebService_Status = "Offline";
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var data = JSON.Parse(Result).AsObject;
|
||||
int version = 0;
|
||||
if (!int.TryParse(data["script_version"], out version))
|
||||
version = 0;
|
||||
int requiredVersion = LocalizationManager.GetRequiredWebServiceVersion();
|
||||
|
||||
if (requiredVersion == version)
|
||||
{
|
||||
mWebService_Status = "Online";
|
||||
ClearErrors();
|
||||
}
|
||||
else
|
||||
{
|
||||
mWebService_Status = "UnsupportedVersion";
|
||||
ShowError("The current Google WebService is not supported.\nPlease, delete the WebService from the Google Drive and Install the latest version.");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
ShowError("Unable to access the WebService");
|
||||
mWebService_Status = "Offline";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Export_Google( eSpreadsheetUpdateMode UpdateMode )
|
||||
{
|
||||
StopConnectionWWW();
|
||||
LanguageSourceData source = GetSourceData();
|
||||
mConnection_WWW = source.Export_Google_CreateWWWcall( UpdateMode );
|
||||
if (mConnection_WWW==null)
|
||||
{
|
||||
OnExported_Google(string.Empty, "WebPlayer can't contact Google");
|
||||
}
|
||||
else
|
||||
{
|
||||
mConnection_Callback = OnExported_Google;
|
||||
EditorApplication.update += CheckForConnection;
|
||||
mConnection_Text = "Uploading spreadsheet";
|
||||
//mConnection_TimeOut = Time.realtimeSinceStartup + 10;
|
||||
}
|
||||
}
|
||||
|
||||
void OnExported_Google( string Result, string Error )
|
||||
{
|
||||
// Checkf or error, but discard the "necessary data rewind wasn't possible" as thats not a real error, just a bug in Unity with POST redirects
|
||||
if (!string.IsNullOrEmpty(Error) && !Error.Contains("rewind"))
|
||||
{
|
||||
Debug.Log (Error);
|
||||
ShowError("Unable to access google");
|
||||
return;
|
||||
}
|
||||
|
||||
if (EditorPrefs.GetBool("I2Loc OpenDataSourceAfterExport", true) && !string.IsNullOrEmpty(GetSourceData().Google_SpreadsheetName))
|
||||
OpenGoogleSpreadsheet(GetSourceData().Google_SpreadsheetKey );
|
||||
mProp_GoogleLiveSyncIsUptoDate.boolValue = true;
|
||||
}
|
||||
|
||||
static void OpenGoogleSpreadsheet( string SpreadsheetKey )
|
||||
{
|
||||
ClearErrors();
|
||||
string SpreadsheetUrl = "https://docs.google.com/spreadsheet/ccc?key=" + SpreadsheetKey;
|
||||
Application.OpenURL(SpreadsheetUrl);
|
||||
}
|
||||
|
||||
public abstract LanguageSourceData GetSourceData();
|
||||
|
||||
|
||||
void Import_Google( eSpreadsheetUpdateMode UpdateMode )
|
||||
{
|
||||
StopConnectionWWW();
|
||||
LanguageSourceData source = GetSourceData();
|
||||
mConnection_WWW = source.Import_Google_CreateWWWcall(true, false);
|
||||
if (mConnection_WWW==null)
|
||||
{
|
||||
OnImported_Google(string.Empty, "Unable to import from google", eSpreadsheetUpdateMode.Replace);
|
||||
}
|
||||
else
|
||||
{
|
||||
mConnection_Callback=null;
|
||||
switch (UpdateMode)
|
||||
{
|
||||
case eSpreadsheetUpdateMode.Replace : mConnection_Callback += OnImported_Google_Replace; break;
|
||||
case eSpreadsheetUpdateMode.Merge : mConnection_Callback += OnImported_Google_Merge; break;
|
||||
case eSpreadsheetUpdateMode.AddNewTerms : mConnection_Callback += OnImported_Google_AddNewTerms; break;
|
||||
}
|
||||
EditorApplication.update += CheckForConnection;
|
||||
mConnection_Text = "Downloading spreadsheet";
|
||||
//mConnection_TimeOut = Time.realtimeSinceStartup + 10;
|
||||
}
|
||||
}
|
||||
|
||||
void OnImported_Google_Replace( string Result, string Error ) { OnImported_Google(Result, Error, eSpreadsheetUpdateMode.Replace); }
|
||||
void OnImported_Google_Merge( string Result, string Error ) { OnImported_Google(Result, Error, eSpreadsheetUpdateMode.Merge); }
|
||||
void OnImported_Google_AddNewTerms( string Result, string Error ) { OnImported_Google(Result, Error, eSpreadsheetUpdateMode.AddNewTerms); }
|
||||
|
||||
void OnImported_Google( string Result, string Error, eSpreadsheetUpdateMode UpdateMode )
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Error))
|
||||
{
|
||||
Debug.Log(Error);
|
||||
ShowError("Unable to access google");
|
||||
return;
|
||||
}
|
||||
LanguageSourceData source = GetSourceData();
|
||||
string ErrorMsg = source.Import_Google_Result(Result, UpdateMode);
|
||||
bool HasErrors = !string.IsNullOrEmpty(ErrorMsg);
|
||||
if (HasErrors)
|
||||
ShowError(ErrorMsg);
|
||||
|
||||
serializedObject.Update();
|
||||
ParseTerms(true, false, !HasErrors);
|
||||
mSelectedKeys.Clear ();
|
||||
mSelectedCategories.Clear();
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
mLanguageSource.GetCategories(false, mSelectedCategories);
|
||||
|
||||
EditorUtility.SetDirty (target);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
void CheckForConnection()
|
||||
{
|
||||
if (mConnection_WWW!=null && mConnection_WWW.isDone)
|
||||
{
|
||||
fnConnectionCallback callback = mConnection_Callback;
|
||||
string Result = string.Empty;
|
||||
string Error = mConnection_WWW.error;
|
||||
|
||||
if (string.IsNullOrEmpty(Error))
|
||||
{
|
||||
// Try first converting with the right encoding
|
||||
var bytes = mConnection_WWW.downloadHandler.data;
|
||||
if (bytes!=null)
|
||||
Result = Encoding.UTF8.GetString(bytes); //mConnection_WWW.text;
|
||||
|
||||
// Fallback to use the default encoding
|
||||
else
|
||||
Result = mConnection_WWW.downloadHandler.text;
|
||||
}
|
||||
|
||||
StopConnectionWWW();
|
||||
if (callback!=null)
|
||||
callback(Result, Error);
|
||||
}
|
||||
/*else
|
||||
if (Time.realtimeSinceStartup > mConnection_TimeOut+30)
|
||||
{
|
||||
fnConnectionCallback callback = mConnection_Callback;
|
||||
StopConnectionWWW();
|
||||
if (callback!=null)
|
||||
callback(string.Empty, "Time Out");
|
||||
}*/
|
||||
}
|
||||
|
||||
void StopConnectionWWW()
|
||||
{
|
||||
EditorApplication.update -= CheckForConnection;
|
||||
mConnection_WWW = null;
|
||||
mConnection_Callback = null;
|
||||
mConnection_Text = string.Empty;
|
||||
}
|
||||
|
||||
#region New Spreadsheet
|
||||
|
||||
void Google_NewSpreadsheet()
|
||||
{
|
||||
#if UNITY_WEBPLAYER
|
||||
ShowError ("Contacting google translation is not yet supported on WebPlayer" );
|
||||
#else
|
||||
|
||||
ClearErrors();
|
||||
string SpreadsheetName;
|
||||
|
||||
LanguageSourceData source = GetSourceData();
|
||||
if (source.IsGlobalSource())
|
||||
SpreadsheetName = string.Format("{0} Localization", PlayerSettings.productName);
|
||||
else
|
||||
SpreadsheetName = string.Format("{0} {1} {2}", PlayerSettings.productName, Editor_GetCurrentScene(), source.ownerObject.name);
|
||||
|
||||
string query = mProp_Google_WebServiceURL.stringValue + "?action=NewSpreadsheet&name=" + Uri.EscapeDataString(SpreadsheetName) + "&password="+ Uri.EscapeDataString(mProp_Google_Password.stringValue);
|
||||
|
||||
mConnection_WWW = UnityWebRequest.Get(query);
|
||||
I2Utils.SendWebRequest(mConnection_WWW);
|
||||
mConnection_Callback = Google_OnNewSpreadsheet;
|
||||
EditorApplication.update += CheckForConnection;
|
||||
mConnection_Text = "Creating Spreadsheet";
|
||||
//mConnection_TimeOut = Time.realtimeSinceStartup + 10;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Google_OnNewSpreadsheet( string Result, string Error )
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Error))
|
||||
{
|
||||
ShowError("Unable to access google");
|
||||
return;
|
||||
}
|
||||
if (Result=="Wrong Password")
|
||||
{
|
||||
ShowError(Result);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var data = JSON.Parse(Result).AsObject;
|
||||
|
||||
string name = data["name"];
|
||||
string key = data["id"];
|
||||
|
||||
serializedObject.Update();
|
||||
mProp_Google_SpreadsheetKey.stringValue = key;
|
||||
mProp_Google_SpreadsheetName.stringValue = name;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
mGoogleSpreadsheets[name] = key;
|
||||
|
||||
LanguageSourceData source = GetSourceData();
|
||||
if (source.mTerms.Count>0 || source.mLanguages.Count>0)
|
||||
Export_Google( eSpreadsheetUpdateMode.Replace );
|
||||
else
|
||||
if (EditorPrefs.GetBool("I2Loc OpenDataSourceAfterExport", true))
|
||||
OpenGoogleSpreadsheet( key );
|
||||
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
ShowError (e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FindSpreadsheets
|
||||
|
||||
void Google_FindSpreadsheets()
|
||||
{
|
||||
ClearErrors();
|
||||
EditorApplication.update -= Google_FindSpreadsheets;
|
||||
string query = mProp_Google_WebServiceURL.stringValue + "?action=GetSpreadsheetList&password="+ Uri.EscapeDataString(mProp_Google_Password.stringValue);
|
||||
mConnection_WWW = UnityWebRequest.Get(query);
|
||||
I2Utils.SendWebRequest(mConnection_WWW);
|
||||
mConnection_Callback = Google_OnFindSpreadsheets;
|
||||
EditorApplication.update += CheckForConnection;
|
||||
mConnection_Text = "Accessing google";
|
||||
//mConnection_TimeOut = Time.realtimeSinceStartup + 10;
|
||||
}
|
||||
|
||||
void Google_OnFindSpreadsheets( string Result, string Error)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Error))
|
||||
{
|
||||
ShowError("Unable to access google");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Result=="Wrong Password")
|
||||
{
|
||||
ShowError(Result);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
mGoogleSpreadsheets.Clear();
|
||||
var data = JSON.Parse(Result).AsObject;
|
||||
foreach (KeyValuePair<string, JSONNode> element in data)
|
||||
mGoogleSpreadsheets[element.Key] = element.Value;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
ShowError (e.Message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 800caf7e364ec2947be099b4f9ed976d
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,339 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
enum eLocalSpreadsheeet { CSV, XLS, XLSX, NONE }
|
||||
|
||||
void OnGUI_Spreadsheet_Local()
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label ("File:", GUILayout.ExpandWidth(false));
|
||||
|
||||
mProp_Spreadsheet_LocalFileName.stringValue = EditorGUILayout.TextField(mProp_Spreadsheet_LocalFileName.stringValue);
|
||||
/*if (GUILayout.Button("...", "toolbarbutton", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
string sFileName = mProp_Spreadsheet_LocalFileName.stringValue;
|
||||
|
||||
string sPath = string.Empty;
|
||||
try {
|
||||
sPath = System.IO.Path.GetDirectoryName(sFileName);
|
||||
}
|
||||
catch( System.Exception e){}
|
||||
|
||||
if (string.IsNullOrEmpty(sPath))
|
||||
sPath = Application.dataPath + "/";
|
||||
|
||||
sFileName = System.IO.Path.GetFileName(sFileName);
|
||||
if (string.IsNullOrEmpty(sFileName))
|
||||
sFileName = "Localization.csv";
|
||||
|
||||
string FullFileName = EditorUtility.SaveFilePanel("Select CSV File", sPath, sFileName, "csv");
|
||||
//string FullFileName = EditorUtility.OpenFilePanel("Select CSV, XLS or XLSX File", sFileName, "csv;*.xls;*.xlsx");
|
||||
|
||||
if (!string.IsNullOrEmpty(FullFileName))
|
||||
{
|
||||
Prop_LocalFileName.stringValue = TryMakingPathRelativeToProject(FullFileName);
|
||||
}
|
||||
}*/
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
//--[ Find current extension ]---------------
|
||||
eLocalSpreadsheeet CurrentExtension = eLocalSpreadsheeet.NONE;
|
||||
//string FileNameLower = Prop_LocalFileName.stringValue.ToLower();
|
||||
/*if (FileNameLower.EndsWith(".csv")) */CurrentExtension = eLocalSpreadsheeet.CSV;
|
||||
/*if (FileNameLower.EndsWith(".xls")) CurrentExtension = eLocalSpreadsheeet.XLS;
|
||||
if (FileNameLower.EndsWith(".xlsx")) CurrentExtension = eLocalSpreadsheeet.XLSX;*/
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
switch (CurrentExtension)
|
||||
{
|
||||
case eLocalSpreadsheeet.NONE :
|
||||
case eLocalSpreadsheeet.CSV :
|
||||
{
|
||||
string FileTypesDesc = "Select or Drag any file of the following types:\n\n";
|
||||
FileTypesDesc+= "*.csv (Comma Separated Values)\n";
|
||||
FileTypesDesc+= "*.txt (CSV file renamed as txt)\n";
|
||||
//FileTypesDesc+= "\n*.xls (Excel 97-2003)";
|
||||
//FileTypesDesc+= "\n*.xlsx (Excel Open XML format)";
|
||||
EditorGUILayout.HelpBox(FileTypesDesc, MessageType.None);
|
||||
}
|
||||
break;
|
||||
case eLocalSpreadsheeet.XLS : EditorGUILayout.HelpBox("Excel 97-2003", MessageType.None); break;
|
||||
case eLocalSpreadsheeet.XLSX : EditorGUILayout.HelpBox("Excel Open XML format", MessageType.None); break;
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
//--[ Allow Dragging files ]-----------------
|
||||
if (GUILayoutUtility.GetLastRect().Contains (UnityEngine.Event.current.mousePosition) && IsValidDraggedLoadSpreadsheet())
|
||||
{
|
||||
if (UnityEngine.Event.current.type == EventType.DragUpdated)
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Link;
|
||||
|
||||
if (UnityEngine.Event.current.type == EventType.DragPerform)
|
||||
{
|
||||
mProp_Spreadsheet_LocalFileName.stringValue = TryMakingPathRelativeToProject( DragAndDrop.paths[0] );
|
||||
DragAndDrop.AcceptDrag();
|
||||
UnityEngine.Event.current.Use();
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
OnGUI_Spreadsheet_Local_ImportExport( CurrentExtension, mProp_Spreadsheet_LocalFileName.stringValue );
|
||||
|
||||
//if (Application.platform == RuntimePlatform.OSXEditor)
|
||||
|
||||
//-- CSV Separator ----------------
|
||||
GUI.changed = false;
|
||||
var CSV_Separator = mProp_Spreadsheet_LocalCSVSeparator.stringValue;
|
||||
if (string.IsNullOrEmpty (CSV_Separator))
|
||||
CSV_Separator = ",";
|
||||
|
||||
GUILayout.Space(10);
|
||||
GUILayout.BeginVertical("Box");
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Separator:");
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Toggle(CSV_Separator==",", "Comma(,)") && CSV_Separator!=",")
|
||||
CSV_Separator = ",";
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Toggle(CSV_Separator==";", "Semicolon(;)") && CSV_Separator!=";")
|
||||
CSV_Separator = ";";
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Toggle(CSV_Separator=="\t", "TAB(\\t)") && CSV_Separator!="\t")
|
||||
CSV_Separator = "\t";
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
//--[ Encoding ]---------------
|
||||
var encodings = Encoding.GetEncodings ().OrderBy(e=>e.Name).ToArray();
|
||||
var encodingNames = encodings.Select(e=>e.Name).ToArray();
|
||||
|
||||
int idx = Array.IndexOf (encodingNames, mProp_Spreadsheet_LocalCSVEncoding.stringValue);
|
||||
if (idx == -1)
|
||||
idx = Array.IndexOf (encodingNames, "utf-8");
|
||||
EditorGUIUtility.labelWidth = 80;
|
||||
|
||||
idx = EditorGUILayout.Popup ("Encoding:", idx, encodingNames);
|
||||
if (GUILayout.Button("Default", GUILayout.ExpandWidth(false)))
|
||||
idx = Array.IndexOf (encodingNames, "utf-8");
|
||||
|
||||
if (idx>=0 && mProp_Spreadsheet_LocalCSVEncoding.stringValue != encodings [idx].Name)
|
||||
mProp_Spreadsheet_LocalCSVEncoding.stringValue = encodings [idx].Name;
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
mProp_Spreadsheet_LocalCSVSeparator.stringValue = CSV_Separator;
|
||||
}
|
||||
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.HelpBox("On some Mac OS, there is a Unity Bug that makes the IDE crash when selecting a CSV file in the Open/Save File Dialog.\nJust by clicking the file, unity tries to preview the content and crashes.\n\nIf any of your the team members use Mac, its adviced to import/export the CSV Files with TXT extension.", MessageType.Warning);
|
||||
GUILayout.Space(10);
|
||||
|
||||
OnGUI_ShowMsg();
|
||||
}
|
||||
|
||||
bool IsValidDraggedLoadSpreadsheet()
|
||||
{
|
||||
if (DragAndDrop.paths==null || DragAndDrop.paths.Length!=1)
|
||||
return false;
|
||||
|
||||
string sPath = DragAndDrop.paths[0].ToLower();
|
||||
if (sPath.EndsWith(".csv")) return true;
|
||||
if (sPath.EndsWith(".txt")) return true;
|
||||
//if (sPath.EndsWith(".xls")) return true;
|
||||
//if (sPath.EndsWith(".xlsx")) return true;
|
||||
|
||||
/*int iChar = sPath.LastIndexOfAny( "/\\.".ToCharArray() );
|
||||
if (iChar<0 || sPath[iChar]!='.')
|
||||
return true;
|
||||
return false;*/
|
||||
return false;
|
||||
}
|
||||
|
||||
string TryMakingPathRelativeToProject( string FileName )
|
||||
{
|
||||
string ProjectPath = Application.dataPath.ToLower();
|
||||
string FileNameLower = FileName.ToLower();
|
||||
|
||||
if (FileNameLower.StartsWith(ProjectPath))
|
||||
FileName = FileName.Substring(ProjectPath.Length+1);
|
||||
else
|
||||
if (FileNameLower.StartsWith("assets/"))
|
||||
FileName = FileName.Substring("assets/".Length);
|
||||
return FileName;
|
||||
}
|
||||
|
||||
void OnGUI_Spreadsheet_Local_ImportExport( eLocalSpreadsheeet CurrentExtension, string File )
|
||||
{
|
||||
GUI.enabled = CurrentExtension!=eLocalSpreadsheeet.NONE;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(10);
|
||||
|
||||
GUI.backgroundColor = Color.Lerp(Color.gray, Color.white, 0.5f);
|
||||
eSpreadsheetUpdateMode Mode = SynchronizationButtons("Import");
|
||||
if ( Mode!= eSpreadsheetUpdateMode.None)
|
||||
Import_Local(File, CurrentExtension, Mode);
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUI.backgroundColor = Color.Lerp(Color.gray, Color.white, 0.5f);
|
||||
Mode = SynchronizationButtons("Export", true);
|
||||
if ( Mode != eSpreadsheetUpdateMode.None)
|
||||
Export_Local(File, CurrentExtension, Mode);
|
||||
|
||||
GUILayout.Space(10);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
EditorGUIUtility.labelWidth += 10;
|
||||
EditorGUILayout.PropertyField(mProp_Spreadsheet_SpecializationAsRows, new GUIContent("Show Specializations as Rows", "true: Make each specialization a separate row (e.g. Term[VR]..., Term[Touch]....\nfalse: Merge specializations into same cell separated by [i2s_XXX]"));
|
||||
EditorGUILayout.PropertyField(mProp_Spreadsheet_SortRows, new GUIContent("Sort Rows", "true: Sort each term by its name....\nfalse: Keep the terms order"));
|
||||
EditorGUIUtility.labelWidth -= 10;
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
void Import_Local( string File, eLocalSpreadsheeet CurrentExtension, eSpreadsheetUpdateMode UpdateMode )
|
||||
{
|
||||
try
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
serializedObject.Update();
|
||||
ClearErrors();
|
||||
|
||||
if (string.IsNullOrEmpty(File))
|
||||
File = Application.dataPath + "/Localization.csv";
|
||||
else
|
||||
if (!Path.IsPathRooted(File))
|
||||
File = string.Concat(Application.dataPath, "/", File);
|
||||
|
||||
// On Mac there is an issue with previewing CSV files, so its forced to only TXT
|
||||
if (Application.platform == RuntimePlatform.OSXEditor)
|
||||
File = EditorUtility.OpenFilePanel("Select a CSV file renamed as TXT", File, "txt");
|
||||
else
|
||||
File = EditorUtility.OpenFilePanel("Select a CSV file or a CSV file renamed as TXT", File, "csv;*.txt");
|
||||
//File = EditorUtility.OpenFilePanel("Select CSV, XLS or XLSX File", File, "csv;*.xls;*.xlsx");
|
||||
if (!string.IsNullOrEmpty(File))
|
||||
{
|
||||
mLanguageSource.Spreadsheet_LocalFileName = TryMakingPathRelativeToProject(File);
|
||||
switch (CurrentExtension)
|
||||
{
|
||||
case eLocalSpreadsheeet.CSV : Import_CSV(File, UpdateMode); break;
|
||||
}
|
||||
ParseTerms(true, false, true);
|
||||
EditorUtility.SetDirty (target);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ShowError("Unable to import file");
|
||||
Debug.LogError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
void Import_CSV( string FileName, eSpreadsheetUpdateMode UpdateMode )
|
||||
{
|
||||
LanguageSourceData source = GetSourceData();
|
||||
var encoding = Encoding.GetEncoding (mProp_Spreadsheet_LocalCSVEncoding.stringValue);
|
||||
if (encoding == null)
|
||||
encoding = Encoding.UTF8;
|
||||
string CSVstring = LocalizationReader.ReadCSVfile (FileName, encoding);
|
||||
|
||||
char Separator = mProp_Spreadsheet_LocalCSVSeparator.stringValue.Length>0 ? mProp_Spreadsheet_LocalCSVSeparator.stringValue[0] : ',';
|
||||
string sError = source.Import_CSV( string.Empty, CSVstring, UpdateMode, Separator);
|
||||
if (!string.IsNullOrEmpty(sError))
|
||||
ShowError(sError);
|
||||
|
||||
mSelectedCategories = source.GetCategories();
|
||||
}
|
||||
|
||||
void Export_Local( string File, eLocalSpreadsheeet CurrentExtension, eSpreadsheetUpdateMode UpdateMode )
|
||||
{
|
||||
try
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
serializedObject.Update();
|
||||
ClearErrors();
|
||||
|
||||
string sPath = string.Empty;
|
||||
if (!Path.IsPathRooted(File))
|
||||
File = string.Concat(Application.dataPath, "/", File);
|
||||
|
||||
try {
|
||||
sPath = Path.GetDirectoryName(File);
|
||||
}
|
||||
catch( Exception){}
|
||||
|
||||
if (string.IsNullOrEmpty(sPath))
|
||||
sPath = Application.dataPath + "/";
|
||||
|
||||
File = Path.GetFileName(File);
|
||||
if (string.IsNullOrEmpty(File))
|
||||
File = "Localization.csv";
|
||||
|
||||
if (Application.platform == RuntimePlatform.OSXEditor)
|
||||
File = EditorUtility.SaveFilePanel("Select a CSV file renamed as TXT", sPath, File, "txt");
|
||||
else
|
||||
File = EditorUtility.SaveFilePanel("Select a CSV or TXT file", sPath, File, "csv;*.txt");
|
||||
if (!string.IsNullOrEmpty(File))
|
||||
{
|
||||
mLanguageSource.Spreadsheet_LocalFileName = TryMakingPathRelativeToProject(File);
|
||||
|
||||
char Separator = mProp_Spreadsheet_LocalCSVSeparator.stringValue.Length>0 ? mProp_Spreadsheet_LocalCSVSeparator.stringValue[0] : ',';
|
||||
var encoding = Encoding.GetEncoding (mProp_Spreadsheet_LocalCSVEncoding.stringValue);
|
||||
if (encoding == null)
|
||||
encoding = Encoding.UTF8;
|
||||
|
||||
switch (CurrentExtension)
|
||||
{
|
||||
case eLocalSpreadsheeet.CSV : Export_CSV(File, UpdateMode, Separator, encoding); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
ShowError("Unable to export file\nCheck it is not READ-ONLY and that\nits not opened in an external viewer");
|
||||
}
|
||||
}
|
||||
|
||||
public void Export_CSV( string FileName, eSpreadsheetUpdateMode UpdateMode, char Separator, Encoding encoding )
|
||||
{
|
||||
LanguageSourceData source = GetSourceData();
|
||||
|
||||
string CSVstring = source.Export_CSV(null, Separator, mProp_Spreadsheet_SpecializationAsRows.boolValue, mProp_Spreadsheet_SortRows.boolValue);
|
||||
File.WriteAllText (FileName, CSVstring, encoding);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fdca66efafe784661b464934cacff065
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,840 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
|
||||
Vector2 mScrollPos_Keys = Vector2.zero;
|
||||
|
||||
public static string mKeyToExplore; // Key that should show all the language details
|
||||
static string KeyList_Filter = "";
|
||||
float mRowSize=-1;
|
||||
float ScrollHeight;
|
||||
float mTermList_MaxWidth = -1;
|
||||
|
||||
public static List<string> mSelectedKeys = new List<string>(); // Selected Keys in the list of mParsedKeys
|
||||
public static List<string> mSelectedCategories = new List<string>();
|
||||
|
||||
|
||||
public enum eFlagsViewKeys
|
||||
{
|
||||
Used = 1<<1,
|
||||
Missing = 1<<2,
|
||||
NotUsed = 1<<3,
|
||||
Untranslated = 1<<4,
|
||||
}
|
||||
public static int mFlagsViewKeys = (int)eFlagsViewKeys.Used | (int)eFlagsViewKeys.NotUsed;
|
||||
|
||||
public static string mTermsList_NewTerm;
|
||||
Rect mKeyListFilterRect;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI Key List
|
||||
|
||||
float ExpandedViewHeight;
|
||||
float TermsListHeight;
|
||||
|
||||
void OnGUI_KeysList(bool AllowExpandKey = true, float Height = 300.0f, bool ShowTools=true)
|
||||
{
|
||||
///if (mTermList_MaxWidth<=0)
|
||||
CalculateTermsListMaxWidth();
|
||||
|
||||
//--[ List Filters ]--------------------------------------
|
||||
|
||||
// The ID of this control is registered here to avoid losing focus when the terms list grows in the scrollbox
|
||||
// This control is drawn later on
|
||||
int KeyListFilterID = GUIUtility.GetControlID( FocusType.Keyboard );
|
||||
|
||||
OnGUI_ShowMsg();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUIStyle bstyle = new GUIStyle ("toolbarbutton");
|
||||
bstyle.fontSize = 15;
|
||||
if (GUILayout.Button (new GUIContent("\u21bb", "Parse Scene and update terms list with missing and unused terms"), bstyle, GUILayout.Width(25)))
|
||||
EditorApplication.update += DoParseTermsInCurrentSceneAndScripts;
|
||||
if (GUILayout.Button(new GUIContent("\u21ea", "Refresh the translation of all Localize objects"), bstyle, GUILayout.Width(25)))
|
||||
CallLocalizeAll();
|
||||
|
||||
GUILayout.Space (1);
|
||||
|
||||
var oldFlags = mFlagsViewKeys;
|
||||
mFlagsViewKeys = OnGUI_FlagToogle("Used","Shows All Terms referenced in the parsed scenes", mFlagsViewKeys, (int)eFlagsViewKeys.Used);
|
||||
mFlagsViewKeys = OnGUI_FlagToogle("Not Used", "Shows all Terms from the Source that are not been used", mFlagsViewKeys, (int)eFlagsViewKeys.NotUsed);
|
||||
mFlagsViewKeys = OnGUI_FlagToogle("Missing","Shows all Terms Used but not defined in the Source", mFlagsViewKeys, (int)eFlagsViewKeys.Missing);
|
||||
|
||||
mFlagsViewKeys = OnGUI_FlagToogle("Untranslated", "Shows all Terms that were not translated to any language", mFlagsViewKeys, (int)eFlagsViewKeys.Untranslated);
|
||||
|
||||
if (oldFlags!=mFlagsViewKeys)
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
|
||||
OnGUI_SelectedCategories();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
/*//if (UnityEngine.Event.current.type == EventType.Repaint)
|
||||
TermsListHeight = Screen.height - 400;
|
||||
Debug.Log(UnityEngine.Event.current.type + " " + TermsListHeight + " " + Screen.height + " " + GUILayoutUtility.GetLastRect().yMax);
|
||||
|
||||
//TermsListHeight = Mathf.Min(Screen.height*0.5f, TermsListHeight);
|
||||
mScrollPos_Keys = GUILayout.BeginScrollView(mScrollPos_Keys, false, false, "horizontalScrollbar", "verticalScrollbar", LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(TermsListHeight));
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
GUILayout.Label("ahhh" + i);
|
||||
GUILayout.EndScrollView();
|
||||
|
||||
return;*/
|
||||
TermsListHeight = Mathf.Min(Screen.height*0.5f, TermsListHeight);
|
||||
|
||||
//--[ Keys List ]-----------------------------------------
|
||||
GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
|
||||
mScrollPos_Keys = GUILayout.BeginScrollView( mScrollPos_Keys, false, false, "horizontalScrollbar", "verticalScrollbar", LocalizeInspector.GUIStyle_OldTextArea ,GUILayout.Height(TermsListHeight)/*GUILayout.MinHeight(Height), GUILayout.MaxHeight(Screen.height), GUILayout.ExpandHeight(true)*/);
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
bool bAnyValidUsage = false;
|
||||
|
||||
mRowSize = EditorStyles.toolbar.fixedHeight;
|
||||
if (UnityEngine.Event.current!=null && UnityEngine.Event.current.type == EventType.Layout)
|
||||
ScrollHeight = mScrollPos_Keys.y;
|
||||
|
||||
float YPosMin = -ScrollHeight;
|
||||
int nSkip = 0;
|
||||
int nDraw = 0;
|
||||
|
||||
if (mShowableTerms.Count == 0 && UnityEngine.Event.current.type == EventType.Layout)
|
||||
UpdateTermsToShownInList ();
|
||||
|
||||
float SkipSize = 0;
|
||||
foreach (var parsedTerm in mShowableTerms)
|
||||
{
|
||||
string sKey = parsedTerm.Term;
|
||||
string sCategory = parsedTerm.Category;
|
||||
string FullKey = parsedTerm.FullTerm;
|
||||
|
||||
int nUses = parsedTerm.Usage;
|
||||
bAnyValidUsage = bAnyValidUsage | (nUses>=0);
|
||||
|
||||
ShowTerm_termData = parsedTerm.termData;
|
||||
|
||||
// Skip lines outside the view -----------------------
|
||||
YPosMin += mRowSize;
|
||||
SkipSize += mRowSize;
|
||||
float YPosMax = YPosMin + mRowSize;
|
||||
bool isExpanded = AllowExpandKey && mKeyToExplore==FullKey;
|
||||
if (!isExpanded && (YPosMax<-2*mRowSize || YPosMin>/*Screen.height*/TermsListHeight+mRowSize))
|
||||
{
|
||||
if (YPosMin>TermsListHeight+mRowSize)
|
||||
break;
|
||||
|
||||
nSkip++;
|
||||
continue;
|
||||
}
|
||||
nDraw++;
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
OnGUI_KeyHeader (sKey, sCategory, FullKey, nUses, YPosMin-mRowSize+mScrollPos_Keys.y);
|
||||
|
||||
//--[ Key Details ]-------------------------------
|
||||
|
||||
if (isExpanded)
|
||||
{
|
||||
GUILayout.Space(SkipSize);
|
||||
SkipSize = 0;
|
||||
OnGUI_KeyList_ShowKeyDetails();
|
||||
Rect rect = GUILayoutUtility.GetLastRect();
|
||||
if (rect.height>5)
|
||||
ExpandedViewHeight = rect.height;
|
||||
YPosMin += ExpandedViewHeight;
|
||||
}
|
||||
}
|
||||
SkipSize += (mShowableTerms.Count - nDraw-nSkip) * mRowSize;
|
||||
GUILayout.Space(SkipSize+2);
|
||||
if (mSelectedCategories.Count < mParsedCategories.Count)
|
||||
{
|
||||
SkipSize += 25;
|
||||
if (GUILayout.Button ("...", EditorStyles.label))
|
||||
{
|
||||
mSelectedCategories.Clear ();
|
||||
mSelectedCategories.AddRange (mParsedCategories);
|
||||
}
|
||||
}
|
||||
OnGUI_KeysList_AddKey();
|
||||
|
||||
GUILayout.Label("", GUILayout.Width(mTermList_MaxWidth+10+30), GUILayout.Height(1));
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
|
||||
TermsListHeight = YPosMin + mRowSize + 25;//SkipSize+25;
|
||||
|
||||
//Rect ListRect = GUILayoutUtility.GetLastRect();
|
||||
//if (ListRect.height>5)
|
||||
// TermsListHeight = ListRect.height;
|
||||
//Debug.Log(nDraw + " " + nSkip + " " + Screen.height + " " + TermsListHeight);
|
||||
|
||||
OnGUI_Keys_ListSelection( KeyListFilterID ); // Selection Buttons
|
||||
|
||||
// if (!bAnyValidUsage)
|
||||
// EditorGUILayout.HelpBox("Use (Tools\\Parse Terms) to find how many times each of the Terms are used", UnityEditor.MessageType.Info);
|
||||
|
||||
if (ShowTools)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUI.enabled = mSelectedKeys.Count>0 || !string.IsNullOrEmpty(mKeyToExplore);
|
||||
if (TestButton (eTest_ActionType.Button_AddSelectedTerms, new GUIContent("Add Terms", "Add terms to Source"), "Button", GUITools.DontExpandWidth)) AddTermsToSource();
|
||||
if (TestButton (eTest_ActionType.Button_RemoveSelectedTerms, new GUIContent("Remove Terms", "Remove Terms from Source"), "Button", GUITools.DontExpandWidth)) RemoveTermsFromSource();
|
||||
|
||||
GUILayout.FlexibleSpace ();
|
||||
|
||||
if (GUILayout.Button ("Change Category")) OpenTool_ChangeCategoryOfSelectedTerms();
|
||||
GUI.enabled = true;
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace ();
|
||||
bool newBool = GUILayout.Toggle(mLanguageSource.CaseInsensitiveTerms, "Case Insensitive Terms");
|
||||
if (newBool != mLanguageSource.CaseInsensitiveTerms)
|
||||
{
|
||||
mProp_CaseInsensitiveTerms.boolValue = newBool;
|
||||
}
|
||||
GUILayout.FlexibleSpace ();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
//Debug.Log ("Draw: " + nDraw + " Skip: " + nSkip);
|
||||
}
|
||||
|
||||
static void ScheduleUpdateTermsToShowInList()
|
||||
{
|
||||
if (!mUpdateShowTermIsScheduled)
|
||||
{
|
||||
EditorApplication.update += UpdateTermsToShownInList;
|
||||
mUpdateShowTermIsScheduled = true;
|
||||
}
|
||||
}
|
||||
static bool mUpdateShowTermIsScheduled;
|
||||
static void UpdateTermsToShownInList()
|
||||
{
|
||||
EditorApplication.update -= UpdateTermsToShownInList;
|
||||
mUpdateShowTermIsScheduled = false;
|
||||
|
||||
mShowableTerms.Clear ();
|
||||
mSelectedCategories.Sort();
|
||||
foreach (KeyValuePair<string, ParsedTerm> kvp in mParsedTerms)
|
||||
{
|
||||
ParsedTerm parsedTerm = kvp.Value;
|
||||
if (ShouldShowTerm (parsedTerm.Term, parsedTerm.Category, parsedTerm.Usage, parsedTerm))
|
||||
mShowableTerms.Add(parsedTerm);
|
||||
}
|
||||
GUITools.RepaintInspectors();
|
||||
GUITools.ScheduleRepaintInspectors();
|
||||
}
|
||||
|
||||
void OnGUI_KeyHeader (string sKey, string sCategory, string FullKey, int nUses, float YPosMin)
|
||||
{
|
||||
//--[ Toggle ]---------------------
|
||||
GUI.Box(new Rect(2, YPosMin+2, 18, mRowSize), "", "Toolbar");
|
||||
OnGUI_SelectableToogleListItem (new Rect(2, YPosMin+3, 15, mRowSize), FullKey, ref mSelectedKeys, "OL Toggle");
|
||||
|
||||
bool bEnabled = mSelectedKeys.Contains (FullKey);
|
||||
//--[ Number of Objects using this key ]---------------------
|
||||
if (nUses >= 0)
|
||||
{
|
||||
if (nUses == 0)
|
||||
{
|
||||
GUI.color = Color.Lerp (Color.gray, Color.white, 0.5f);
|
||||
GUI.Label (new Rect(20, YPosMin+2, 30, mRowSize), nUses.ToString (), "toolbarbutton");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUI.Button(new Rect(20, YPosMin + 2, 30, mRowSize), nUses.ToString(), "toolbarbutton"))
|
||||
{
|
||||
List<string> selection = new List<string>(mSelectedKeys);
|
||||
if (!selection.Contains(FullKey))
|
||||
selection.Add(FullKey);
|
||||
|
||||
List<GameObject> selGOs = new List<GameObject>();
|
||||
for (int i=0; i<selection.Count; ++i)
|
||||
selGOs.AddRange( FindObjectsUsingKey(selection[i]) );
|
||||
|
||||
|
||||
if (selGOs.Count > 0)
|
||||
Selection.objects = selGOs.ToArray();
|
||||
else
|
||||
ShowWarning("The selected Terms are not used in this Scene. Try opening other scenes");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.color = Color.Lerp (Color.red, Color.white, 0.6f);
|
||||
if (GUI.Button (new Rect(20, YPosMin+2, 30, mRowSize), "", "toolbarbutton"))
|
||||
{
|
||||
mCurrentToolsMode = eToolsMode.Parse;
|
||||
mCurrentViewMode = eViewMode.Tools;
|
||||
}
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
|
||||
TermData termData = ShowTerm_termData!=null ? ShowTerm_termData : mLanguageSource.GetTermData (FullKey);
|
||||
bool bKeyIsMissing = termData == null;
|
||||
float MinX = 50;
|
||||
if (bKeyIsMissing)
|
||||
{
|
||||
Rect rect = new Rect(50, YPosMin+2, mRowSize, mRowSize+2);
|
||||
GUITools.DrawSkinIcon(rect, "CN EntryWarnIcon", "CN EntryWarn");
|
||||
GUI.Label (rect, new GUIContent ("", "This term is used in the scene, but its not localized in the Language Source"));
|
||||
MinX += rect.width;
|
||||
}
|
||||
else MinX += 3;
|
||||
|
||||
float listWidth = Mathf.Max(EditorGUIUtility.currentViewWidth / EditorGUIUtility.pixelsPerPoint, mTermList_MaxWidth);
|
||||
Rect rectKey = new Rect(MinX, YPosMin+2, listWidth-MinX, mRowSize);
|
||||
if (sCategory != LanguageSourceData.EmptyCategory)
|
||||
rectKey.width -= 130;
|
||||
if (mKeyToExplore == FullKey)
|
||||
{
|
||||
GUI.backgroundColor = Color.Lerp (Color.blue, Color.white, 0.8f);
|
||||
if (GUI.Button (rectKey, new GUIContent (sKey, EditorStyles.foldout.onNormal.background), LocalizeInspector.GUIStyle_OldTextArea))
|
||||
{
|
||||
mKeyToExplore = string.Empty;
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
ClearErrors ();
|
||||
}
|
||||
GUI.backgroundColor = Color.white;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIStyle LabelStyle = EditorStyles.label;
|
||||
if (!bKeyIsMissing && !TermHasAllTranslations (mLanguageSource, termData))
|
||||
{
|
||||
LabelStyle = new GUIStyle (EditorStyles.label);
|
||||
LabelStyle.fontStyle = FontStyle.Italic;
|
||||
GUI.color = Color.Lerp (Color.white, Color.yellow, 0.5f);
|
||||
}
|
||||
if (!bEnabled)
|
||||
GUI.contentColor = Color.Lerp (Color.gray, Color.white, 0.3f);
|
||||
if (GUI.Button (rectKey, sKey, LabelStyle))
|
||||
{
|
||||
SelectTerm (FullKey);
|
||||
ClearErrors ();
|
||||
}
|
||||
if (!bEnabled)
|
||||
GUI.contentColor = Color.white;
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
//--[ Category ]--------------------------
|
||||
if (sCategory != LanguageSourceData.EmptyCategory)
|
||||
{
|
||||
if (mKeyToExplore == FullKey)
|
||||
{
|
||||
rectKey.x = listWidth - 100-38-20;
|
||||
rectKey.width = 130;
|
||||
if (GUI.Button (rectKey, sCategory, EditorStyles.toolbarButton))
|
||||
OpenTool_ChangeCategoryOfSelectedTerms ();
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIStyle stl = new GUIStyle(EditorStyles.miniLabel);
|
||||
stl.alignment = TextAnchor.MiddleRight;
|
||||
rectKey.width = 130;//EditorStyles.miniLabel.CalcSize(new GUIContent(sCategory)).x;
|
||||
rectKey.x = listWidth - rectKey.width - 38-20;
|
||||
|
||||
if (GUI.Button (rectKey, sCategory, stl))
|
||||
{
|
||||
SelectTerm (FullKey);
|
||||
ClearErrors ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CalculateTermsListMaxWidth()
|
||||
{
|
||||
mTermList_MaxWidth = EditorGUIUtility.currentViewWidth / EditorGUIUtility.pixelsPerPoint - 120;
|
||||
/*float maxWidth = Screen.width / 18;
|
||||
foreach (KeyValuePair<string, ParsedTerm> kvp in mParsedTerms)
|
||||
{
|
||||
var txt = kvp.Key;
|
||||
if (txt.Length > 100)
|
||||
txt = txt.Substring(0, 100);
|
||||
var size = EditorStyles.label.CalcSize(new GUIContent(txt));
|
||||
mTermList_MaxWidth = Mathf.Max (mTermList_MaxWidth, size.x);
|
||||
}*/
|
||||
}
|
||||
|
||||
bool TermHasAllTranslations( LanguageSourceData source, TermData data )
|
||||
{
|
||||
if (source==null) source = LocalizationManager.Sources[0];
|
||||
for (int i=0, imax=data.Languages.Length; i<imax; ++i)
|
||||
{
|
||||
bool isLangEnabled = source.mLanguages.Count>i ? source.mLanguages[i].IsEnabled() : true;
|
||||
if (string.IsNullOrEmpty(data.Languages[i]) && isLangEnabled)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnGUI_KeysList_AddKey()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUI.color = Color.Lerp(Color.gray, Color.white, 0.5f);
|
||||
bool bWasEnabled = mTermsList_NewTerm!=null;
|
||||
bool bEnabled = !GUILayout.Toggle (!bWasEnabled, "+", EditorStyles.toolbarButton, GUILayout.Width(30));
|
||||
GUI.color = Color.white;
|
||||
|
||||
if (bWasEnabled && !bEnabled) mTermsList_NewTerm = null;
|
||||
if (!bWasEnabled && bEnabled) mTermsList_NewTerm = string.Empty;
|
||||
|
||||
if (bEnabled)
|
||||
{
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
mTermsList_NewTerm = EditorGUILayout.TextField(mTermsList_NewTerm, EditorStyles.toolbarTextField, GUILayout.ExpandWidth(true));
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
LanguageSourceData.ValidateFullTerm( ref mTermsList_NewTerm );
|
||||
if (string.IsNullOrEmpty(mTermsList_NewTerm) || mLanguageSource.ContainsTerm(mTermsList_NewTerm) || mTermsList_NewTerm=="-")
|
||||
GUI.enabled = false;
|
||||
|
||||
if (TestButton (eTest_ActionType.Button_AddTerm_InTermsList, "Create Key", "toolbarbutton", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
AddLocalTerm(mTermsList_NewTerm);
|
||||
SelectTerm( mTermsList_NewTerm );
|
||||
ClearErrors();
|
||||
mTermsList_NewTerm = null;
|
||||
SetAllTerms_When_InferredTerms_IsInSource ();
|
||||
}
|
||||
GUI.enabled = true;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void OpenTool_ChangeCategoryOfSelectedTerms()
|
||||
{
|
||||
mCurrentViewMode = eViewMode.Tools;
|
||||
mCurrentToolsMode = eToolsMode.Categorize;
|
||||
if (!string.IsNullOrEmpty(mKeyToExplore) && !mSelectedKeys.Contains(mKeyToExplore))
|
||||
mSelectedKeys.Add(mKeyToExplore);
|
||||
mSelectedKeys.Sort();
|
||||
}
|
||||
|
||||
void OnGUI_SelectedCategories()
|
||||
{
|
||||
if (mParsedCategories.Count == 0)
|
||||
return;
|
||||
|
||||
string text = "Categories";
|
||||
if (mSelectedCategories.Count() == 0)
|
||||
text = "Nothing";
|
||||
else
|
||||
if (mSelectedCategories.Count() == mParsedCategories.Count)
|
||||
text = "Everything";
|
||||
else
|
||||
text = mSelectedCategories.Count + " categories";
|
||||
|
||||
if (GUILayout.Button(new GUIContent(text), "toolbarbutton", GUILayout.Width(100)))
|
||||
{
|
||||
var menu = new GenericMenu();
|
||||
|
||||
menu.AddItem(new GUIContent("Everything"), false, () =>
|
||||
{
|
||||
mSelectedCategories.Clear();
|
||||
mSelectedCategories.AddRange(mParsedCategories);
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
});
|
||||
menu.AddItem(new GUIContent("Nothing"), false, () =>
|
||||
{
|
||||
mSelectedCategories.Clear();
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
});
|
||||
menu.AddSeparator("");
|
||||
|
||||
var parsedList = mParsedCategories.OrderBy(x=>x).ToList();
|
||||
for (int i=0, imax=parsedList.Count; i<imax ; ++i)
|
||||
{
|
||||
var category = parsedList[i];
|
||||
var nextCategory = i + 1 < imax ? parsedList[i + 1] : null;
|
||||
|
||||
bool isHeader = nextCategory != null && nextCategory.StartsWith(category + "/");
|
||||
|
||||
var displayName = category;
|
||||
var categoryRoot = category;
|
||||
if (isHeader)
|
||||
{
|
||||
categoryRoot += "/";
|
||||
var newCateg = !category.Contains('/') ? category : category.Substring(category.LastIndexOf('/') + 1);
|
||||
displayName = categoryRoot + newCateg;
|
||||
}
|
||||
|
||||
menu.AddItem(new GUIContent(displayName), !string.IsNullOrEmpty(mSelectedCategories.FirstOrDefault(x=>x.StartsWith(categoryRoot))), () =>
|
||||
{
|
||||
var CatHeader = category + "/";
|
||||
if (mSelectedCategories.Contains(category))
|
||||
{
|
||||
mSelectedCategories.Remove(category);
|
||||
|
||||
if (isHeader)
|
||||
{
|
||||
mSelectedCategories.RemoveAll(x => x.StartsWith(CatHeader));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mSelectedCategories.Add(category);
|
||||
if (isHeader)
|
||||
{
|
||||
mSelectedCategories.AddRange( parsedList.Where(x=>x.StartsWith(CatHeader)));
|
||||
}
|
||||
}
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
});
|
||||
if (isHeader)
|
||||
{
|
||||
menu.AddSeparator(category+"/");
|
||||
}
|
||||
}
|
||||
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
}
|
||||
|
||||
void SaveSelectedCategories()
|
||||
{
|
||||
if (mSelectedCategories.Count == 0) {
|
||||
EditorPrefs.DeleteKey ("I2 CategoryFilter");
|
||||
} else {
|
||||
var data = string.Join(",", mSelectedCategories.ToArray());
|
||||
EditorPrefs.SetString ("I2 CategoryFilter", data);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadSelectedCategories()
|
||||
{
|
||||
var data = EditorPrefs.GetString ("I2 CategoryFilter", null);
|
||||
if (!string.IsNullOrEmpty(data))
|
||||
{
|
||||
mSelectedCategories.Clear ();
|
||||
mSelectedCategories.AddRange( data.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Bottom part of the Key list (buttons: All, None, Used,... to select the keys)
|
||||
void OnGUI_Keys_ListSelection ( int KeyListFilterID )
|
||||
{
|
||||
GUILayout.BeginHorizontal( "toolbarbutton" );
|
||||
|
||||
if (TestButton( eTest_ActionType.Button_SelectTerms_All, new GUIContent( "All", "Selects All Terms in the list" ), "toolbarbutton", GUILayout.ExpandWidth( false ) ))
|
||||
{
|
||||
mSelectedKeys.Clear();
|
||||
foreach (var kvp in mParsedTerms)
|
||||
if (ShouldShowTerm( kvp.Value.Term, kvp.Value.Category, kvp.Value.Usage ))
|
||||
mSelectedKeys.Add( kvp.Key );
|
||||
}
|
||||
if (GUILayout.Button( new GUIContent( "None", "Clears the selection" ), "toolbarbutton", GUILayout.ExpandWidth( false ) )) { mSelectedKeys.Clear(); }
|
||||
GUILayout.Space( 5 );
|
||||
|
||||
GUI.enabled = (mFlagsViewKeys & (int)eFlagsViewKeys.Used)>1;
|
||||
if (TestButton(eTest_ActionType.Button_SelectTerms_Used, new GUIContent( "Used", "Selects All Terms referenced in the parsed scenes" ), "toolbarbutton", GUILayout.ExpandWidth( false ) ))
|
||||
{
|
||||
mSelectedKeys.Clear();
|
||||
foreach (var kvp in mParsedTerms)
|
||||
if (kvp.Value.Usage > 0 && ShouldShowTerm( kvp.Value.Term, kvp.Value.Category, kvp.Value.Usage ))
|
||||
mSelectedKeys.Add( kvp.Key );
|
||||
}
|
||||
GUI.enabled = (mFlagsViewKeys & (int)eFlagsViewKeys.NotUsed)>1;
|
||||
if (GUILayout.Button( new GUIContent( "Not Used", "Selects all Terms from the Source that are not been used" ), "toolbarbutton", GUILayout.ExpandWidth( false ) ))
|
||||
{
|
||||
mSelectedKeys.Clear();
|
||||
foreach (var kvp in mParsedTerms)
|
||||
if (kvp.Value.Usage == 0 && ShouldShowTerm( kvp.Value.Term, kvp.Value.Category, kvp.Value.Usage ))
|
||||
mSelectedKeys.Add( kvp.Key );
|
||||
}
|
||||
|
||||
GUI.enabled = (mFlagsViewKeys & (int)eFlagsViewKeys.Missing)>1;
|
||||
if (TestButton(eTest_ActionType.Button_SelectTerms_Missing, new GUIContent( "Missing", "Selects all Terms Used but not defined in the Source" ), "toolbarbutton", GUILayout.ExpandWidth( false ) ))
|
||||
{
|
||||
mSelectedKeys.Clear();
|
||||
foreach (var kvp in mParsedTerms)
|
||||
if (!mLanguageSource.ContainsTerm( kvp.Key ) && ShouldShowTerm( kvp.Value.Term, kvp.Value.Category, kvp.Value.Usage ))
|
||||
mSelectedKeys.Add( kvp.Key );
|
||||
}
|
||||
|
||||
GUI.enabled = ((mFlagsViewKeys & (int)eFlagsViewKeys.Untranslated) > 1);
|
||||
if (GUILayout.Button(new GUIContent("Untranslated", "Selects all Terms from the Source that are not translated to any language"), "toolbarbutton", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
mSelectedKeys.Clear();
|
||||
foreach (var kvp in mParsedTerms)
|
||||
if (kvp.Value.termData.Languages.All(o => string.IsNullOrEmpty(o)) && ShouldShowTerm(kvp.Value.Term, kvp.Value.Category, kvp.Value.Usage))
|
||||
mSelectedKeys.Add(kvp.Key);
|
||||
}
|
||||
|
||||
GUI.enabled = true;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
// Terms Filter
|
||||
{
|
||||
//KeyList_Filter = EditorGUILayout.TextField(KeyList_Filter, GUI.skin.GetStyle(GUITools.Style_ToolbarSearchTextField), GUILayout.ExpandWidth(true));
|
||||
GUILayout.Label( "", GUILayout.ExpandWidth( true ) );
|
||||
mKeyListFilterRect = GUILayoutUtility.GetLastRect();
|
||||
mKeyListFilterRect.xMax += 4;
|
||||
|
||||
KeyList_Filter = GUITools.TextField( mKeyListFilterRect, KeyList_Filter, 255, GUI.skin.GetStyle( GUITools.Style_ToolbarSearchTextField ), KeyListFilterID );
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (GUILayout.Button( string.Empty, string.IsNullOrEmpty( KeyList_Filter ) ? GUITools.Style_ToolbarSearchCancelButtonEmpty : GUITools.Style_ToolbarSearchCancelButton, GUILayout.ExpandWidth( false ) ))
|
||||
{
|
||||
KeyList_Filter = string.Empty;
|
||||
EditorApplication.update += RepaintScene;
|
||||
GUI.FocusControl( "" );
|
||||
}
|
||||
|
||||
string filterHelp = "Fiter Options:\ntext - shows all key/categories matching text\nc text - shows all terms of the text category\nf text - show terms having 'text' in their translations";
|
||||
GUILayout.Space(-5);
|
||||
GUI.contentColor = new Color(1, 1, 1, 0.5f);
|
||||
GUILayout.Label(new GUIContent(GUITools.Icon_Help.image, filterHelp), GUITools.DontExpandWidth);
|
||||
GUI.contentColor = GUITools.White;
|
||||
GUILayout.Space(-5);
|
||||
|
||||
|
||||
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
mShowableTerms.Clear();
|
||||
GUI.changed = false;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Filtering
|
||||
|
||||
public bool ShouldShowTerm (string FullTerm)
|
||||
{
|
||||
ParsedTerm termData;
|
||||
if (!mParsedTerms.TryGetValue(FullTerm, out termData))
|
||||
return false;
|
||||
|
||||
return ShouldShowTerm (termData.Term, termData.Category, termData.Usage, termData);
|
||||
}
|
||||
|
||||
private static TermData ShowTerm_termData;
|
||||
public static bool ShouldShowTerm (string Term, string Category, int nUses, ParsedTerm parsedTerm=null )
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Category) && !mSelectedCategories.Contains(Category))
|
||||
return false;
|
||||
if (Term == "-")
|
||||
return false;
|
||||
|
||||
|
||||
var fullTerm = Term;
|
||||
if (!string.IsNullOrEmpty(Category) && Category != LanguageSourceData.EmptyCategory)
|
||||
fullTerm = Category + "/" + Term;
|
||||
|
||||
if (parsedTerm != null && parsedTerm.termData != null)
|
||||
ShowTerm_termData = parsedTerm.termData;
|
||||
else
|
||||
{
|
||||
ShowTerm_termData = mLanguageSource.GetTermData (fullTerm);
|
||||
if (parsedTerm!=null)
|
||||
parsedTerm.termData = ShowTerm_termData;
|
||||
}
|
||||
|
||||
var filter = KeyList_Filter.Trim();
|
||||
bool useTranslation = filter.StartsWith("f ", StringComparison.OrdinalIgnoreCase);
|
||||
if (useTranslation)
|
||||
{
|
||||
if (ShowTerm_termData == null)
|
||||
return false;
|
||||
|
||||
filter = filter.Substring(2).Trim();
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
{
|
||||
bool hasFilter = false;
|
||||
for (int i = 0; i < ShowTerm_termData.Languages.Length; ++i)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ShowTerm_termData.Languages[i])
|
||||
&& StringContainsFilter(ShowTerm_termData.Languages[i], filter))
|
||||
{
|
||||
hasFilter = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (!hasFilter)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool onlyCategory = filter.StartsWith("c ", StringComparison.OrdinalIgnoreCase);
|
||||
if (onlyCategory)
|
||||
filter = filter.Substring(2).Trim();
|
||||
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
{
|
||||
bool matchesCategory = StringContainsFilter(Category, filter);
|
||||
bool matchesName = !onlyCategory && StringContainsFilter(Term, filter);
|
||||
|
||||
if (!matchesCategory && !matchesName)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool bIsMissing = ShowTerm_termData == null;
|
||||
bool hasTranslation = !bIsMissing && ShowTerm_termData.Languages.Any(o => !string.IsNullOrEmpty(o));
|
||||
|
||||
if ((mFlagsViewKeys & (int)eFlagsViewKeys.Untranslated) > 0) return !hasTranslation;
|
||||
|
||||
if (nUses<0) return true;
|
||||
|
||||
|
||||
if ((mFlagsViewKeys & (int)eFlagsViewKeys.Missing)>0 && bIsMissing) return true;
|
||||
if ((mFlagsViewKeys & (int)eFlagsViewKeys.Missing)==0 && bIsMissing) return false;
|
||||
|
||||
if ((mFlagsViewKeys & (int)eFlagsViewKeys.Used)>0 && nUses>0) return true;
|
||||
if ((mFlagsViewKeys & (int)eFlagsViewKeys.NotUsed)>0 && nUses==0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool StringContainsFilter( string Term, string Filter )
|
||||
{
|
||||
if (string.IsNullOrEmpty(Filter) || string.IsNullOrEmpty(Term))
|
||||
return true;
|
||||
if (Term == "-")
|
||||
return false;
|
||||
Term = Term.ToLower();
|
||||
string[] Filters = Filter.ToLower().Split(";, ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int i = 0, imax = Filters.Length; i < imax; ++i)
|
||||
if (Term.Contains(Filters[i]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Add/Remove Keys to DB
|
||||
|
||||
void AddTermsToSource()
|
||||
{
|
||||
if (!string.IsNullOrEmpty (mKeyToExplore) && !mSelectedKeys.Contains(mKeyToExplore))
|
||||
mSelectedKeys.Add (mKeyToExplore);
|
||||
|
||||
for (int i=mSelectedKeys.Count-1; i>=0; --i)
|
||||
{
|
||||
string key = mSelectedKeys[i];
|
||||
|
||||
if (!ShouldShowTerm(key))
|
||||
continue;
|
||||
|
||||
AddLocalTerm(key);
|
||||
mSelectedKeys.RemoveAt(i);
|
||||
}
|
||||
SetAllTerms_When_InferredTerms_IsInSource ();
|
||||
}
|
||||
|
||||
void RemoveTermsFromSource()
|
||||
{
|
||||
if (mTestAction==eTest_ActionType.None && !EditorUtility.DisplayDialog("Confirm delete", "Are you sure you want to delete the selected terms", "Yes", "Cancel"))
|
||||
return;
|
||||
|
||||
if (!string.IsNullOrEmpty (mKeyToExplore) && !mSelectedKeys.Contains(mKeyToExplore))
|
||||
mSelectedKeys.Add (mKeyToExplore);
|
||||
|
||||
for (int i=mSelectedKeys.Count-1; i>=0; --i)
|
||||
{
|
||||
string key = mSelectedKeys[i];
|
||||
|
||||
if (!ShouldShowTerm(key))
|
||||
continue;
|
||||
|
||||
mLanguageSource.RemoveTerm(key);
|
||||
RemoveParsedTerm(key);
|
||||
mSelectedKeys.Remove(key);
|
||||
}
|
||||
|
||||
mKeyToExplore = string.Empty;
|
||||
mTermList_MaxWidth = -1;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
mLanguageSource.Editor_SetDirty();
|
||||
|
||||
EditorApplication.update += DoParseTermsInCurrentScene;
|
||||
EditorApplication.update += RepaintScene;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Select Objects in Current Scene
|
||||
|
||||
|
||||
public static void SelectTerm( string Key, bool SwitchToKeysTab=false )
|
||||
{
|
||||
GUI.FocusControl(null);
|
||||
mKeyToExplore = Key;
|
||||
mKeysDesc_AllowEdit = false;
|
||||
if (SwitchToKeysTab)
|
||||
mCurrentViewMode = eViewMode.Keys;
|
||||
}
|
||||
|
||||
|
||||
void SelectObjectsUsingKey( string Key )
|
||||
{
|
||||
List<GameObject> SelectedObjs = FindObjectsUsingKey(Key);
|
||||
|
||||
if (SelectedObjs.Count>0)
|
||||
Selection.objects = SelectedObjs.ToArray();
|
||||
else
|
||||
ShowWarning("The selected Terms are not used in this Scene. Try opening other scenes");
|
||||
}
|
||||
|
||||
List<GameObject> FindObjectsUsingKey(string Key)
|
||||
{
|
||||
List<GameObject> SelectedObjs = new List<GameObject>();
|
||||
|
||||
Localize[] Locals = (Localize[])Resources.FindObjectsOfTypeAll(typeof(Localize));
|
||||
|
||||
if (Locals == null)
|
||||
return SelectedObjs;
|
||||
|
||||
for (int i = 0, imax = Locals.Length; i < imax; ++i)
|
||||
{
|
||||
Localize localize = Locals[i];
|
||||
if (localize == null || localize.gameObject == null || !GUITools.ObjectExistInScene(localize.gameObject))
|
||||
continue;
|
||||
|
||||
string Term, SecondaryTerm;
|
||||
localize.GetFinalTerms(out Term, out SecondaryTerm);
|
||||
|
||||
if (Key == Term || Key == SecondaryTerm)
|
||||
SelectedObjs.Add(localize.gameObject);
|
||||
}
|
||||
|
||||
return SelectedObjs;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
[MenuItem("Tools/I2 Localization/Refresh Localizations", false, 16)]
|
||||
public static void CallLocalizeAll()
|
||||
{
|
||||
LocalizationManager.LocalizeAll(true);
|
||||
HandleUtility.Repaint();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f0230a94fc864d5bb1f2261de16edce
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,785 @@
|
||||
//#define UGUI
|
||||
//#define NGUI
|
||||
|
||||
using System;
|
||||
using TMPro;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
internal static bool mKeysDesc_AllowEdit;
|
||||
internal static string GUI_SelectedSpecialization
|
||||
{
|
||||
get{
|
||||
if (string.IsNullOrEmpty(mGUI_SelectedSpecialization))
|
||||
mGUI_SelectedSpecialization = EditorPrefs.GetString ("I2Loc Specialization", "Any");
|
||||
return mGUI_SelectedSpecialization;
|
||||
}
|
||||
set{
|
||||
if (value!=mGUI_SelectedSpecialization)
|
||||
EditorPrefs.SetString ("I2Loc Specialization", value);
|
||||
mGUI_SelectedSpecialization = value;
|
||||
}
|
||||
}
|
||||
internal static string mGUI_SelectedSpecialization;
|
||||
|
||||
internal static bool GUI_ShowDisabledLanguagesTranslation = true;
|
||||
|
||||
internal static int mShowPlural = -1;
|
||||
#endregion
|
||||
|
||||
#region Key Description
|
||||
|
||||
void OnGUI_KeyList_ShowKeyDetails()
|
||||
{
|
||||
GUI.backgroundColor = Color.Lerp(Color.blue, Color.white, 0.9f);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
OnGUI_Keys_Languages(mKeyToExplore, null);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (TestButton(eTest_ActionType.Button_DeleteTerm, "Delete", "Button", GUILayout.ExpandWidth(true)))
|
||||
{
|
||||
if (mTestAction != eTest_ActionType.None || EditorUtility.DisplayDialog("Confirm delete", "Are you sure you want to delete term '" + mKeyToExplore + "'", "Yes", "Cancel"))
|
||||
EditorApplication.update += DeleteCurrentKey;
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Rename"))
|
||||
{
|
||||
mCurrentViewMode = eViewMode.Tools;
|
||||
mCurrentToolsMode = eToolsMode.Merge;
|
||||
if (!mSelectedKeys.Contains(mKeyToExplore))
|
||||
mSelectedKeys.Add(mKeyToExplore);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
GUI.backgroundColor = Color.white;
|
||||
}
|
||||
|
||||
void DeleteTerm( string Term, bool updateStructures = true )
|
||||
{
|
||||
mLanguageSource.RemoveTerm (Term);
|
||||
RemoveParsedTerm(Term);
|
||||
mSelectedKeys.Remove(Term);
|
||||
|
||||
if (Term==mKeyToExplore)
|
||||
mKeyToExplore = string.Empty;
|
||||
|
||||
if (updateStructures)
|
||||
{
|
||||
UpdateParsedCategories();
|
||||
mTermList_MaxWidth = -1;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
mLanguageSource.Editor_SetDirty();
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
}
|
||||
EditorApplication.update += RepaintScene;
|
||||
}
|
||||
|
||||
void RepaintScene()
|
||||
{
|
||||
EditorApplication.update -= RepaintScene;
|
||||
Repaint();
|
||||
}
|
||||
|
||||
void DeleteCurrentKey()
|
||||
{
|
||||
EditorApplication.update -= DeleteCurrentKey;
|
||||
DeleteTerm (mKeyToExplore);
|
||||
|
||||
mKeyToExplore = "";
|
||||
EditorApplication.update += DoParseTermsInCurrentScene;
|
||||
}
|
||||
|
||||
TermData AddLocalTerm( string Term, bool AutoSelect = true )
|
||||
{
|
||||
var data = AddTerm(Term, AutoSelect);
|
||||
if (data==null)
|
||||
return null;
|
||||
|
||||
mTermList_MaxWidth = -1;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
mLanguageSource.Editor_SetDirty();
|
||||
return data;
|
||||
}
|
||||
|
||||
static TermData AddTerm(string Term, bool AutoSelect = true, eTermType termType = eTermType.Text)
|
||||
{
|
||||
if (Term == "-" || string.IsNullOrEmpty(Term))
|
||||
return null;
|
||||
|
||||
Term = I2Utils.GetValidTermName(Term, true);
|
||||
|
||||
TermData data = mLanguageSource.AddTerm(Term, termType);
|
||||
GetParsedTerm(Term);
|
||||
string sCategory = LanguageSourceData.GetCategoryFromFullTerm(Term);
|
||||
mParsedCategories.Add(sCategory);
|
||||
|
||||
if (AutoSelect)
|
||||
{
|
||||
if (!mSelectedKeys.Contains(Term))
|
||||
mSelectedKeys.Add(Term);
|
||||
|
||||
if (!mSelectedCategories.Contains(sCategory))
|
||||
mSelectedCategories.Add(sCategory);
|
||||
}
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
mLanguageSource.Editor_SetDirty();
|
||||
return data;
|
||||
}
|
||||
|
||||
// this method shows the key description and the localization to each language
|
||||
public static TermData OnGUI_Keys_Languages( string Key, Localize localizeCmp, bool IsPrimaryKey=true )
|
||||
{
|
||||
if (Key==null)
|
||||
Key = string.Empty;
|
||||
|
||||
TermData termdata = null;
|
||||
|
||||
LanguageSourceData source = mLanguageSource;
|
||||
if (localizeCmp != null && localizeCmp.Source != null)
|
||||
source = localizeCmp.Source.SourceData;
|
||||
|
||||
if (source==null)
|
||||
source = LocalizationManager.GetSourceContaining(Key, false);
|
||||
|
||||
if (source==null)
|
||||
{
|
||||
if (localizeCmp == null)
|
||||
source = LocalizationManager.Sources[0];
|
||||
else
|
||||
source = LocalizationManager.GetSourceContaining(IsPrimaryKey ? localizeCmp.SecondaryTerm : localizeCmp.Term);
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(Key))
|
||||
{
|
||||
EditorGUILayout.HelpBox( "Select a Term to Localize", MessageType.Info );
|
||||
return null;
|
||||
}
|
||||
|
||||
termdata = source.GetTermData(Key);
|
||||
if (termdata==null && localizeCmp!=null)
|
||||
{
|
||||
var realSource = LocalizationManager.GetSourceContaining(Key, false);
|
||||
if (realSource != null)
|
||||
{
|
||||
termdata = realSource.GetTermData(Key);
|
||||
source = realSource;
|
||||
}
|
||||
}
|
||||
if (termdata==null)
|
||||
{
|
||||
if (Key == "-")
|
||||
return null;
|
||||
EditorGUILayout.HelpBox( string.Format("Key '{0}' is not Localized or it is in a different Language Source", Key), MessageType.Error );
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Add Term to Source"))
|
||||
{
|
||||
var termType = eTermType.Text;
|
||||
if (localizeCmp!=null && localizeCmp.mLocalizeTarget != null)
|
||||
{
|
||||
termType = IsPrimaryKey ? localizeCmp.mLocalizeTarget.GetPrimaryTermType(localizeCmp)
|
||||
: localizeCmp.mLocalizeTarget.GetSecondaryTermType(localizeCmp);
|
||||
}
|
||||
|
||||
AddTerm(Key, true, termType);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//--[ Type ]----------------------------------
|
||||
if (localizeCmp==null)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label ("Type:", GUILayout.ExpandWidth(false));
|
||||
eTermType NewType = (eTermType)EditorGUILayout.EnumPopup(termdata.TermType, GUILayout.ExpandWidth(true));
|
||||
if (termdata.TermType != NewType)
|
||||
termdata.TermType = NewType;
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
//--[ Description ]---------------------------
|
||||
|
||||
mKeysDesc_AllowEdit = GUILayout.Toggle(mKeysDesc_AllowEdit, "Description", EditorStyles.foldout, GUILayout.ExpandWidth(true));
|
||||
|
||||
if (mKeysDesc_AllowEdit)
|
||||
{
|
||||
string NewDesc = EditorGUILayout.TextArea( termdata.Description, Style_WrapTextField );
|
||||
if (NewDesc != termdata.Description)
|
||||
{
|
||||
termdata.Description = NewDesc;
|
||||
source.Editor_SetDirty();
|
||||
}
|
||||
}
|
||||
else
|
||||
EditorGUILayout.HelpBox( string.IsNullOrEmpty(termdata.Description) ? "No description" : termdata.Description, MessageType.Info );
|
||||
|
||||
OnGUI_Keys_Language_SpecializationsBar (termdata, source);
|
||||
|
||||
OnGUI_Keys_Languages(Key, ref termdata, localizeCmp, IsPrimaryKey, source);
|
||||
return termdata;
|
||||
}
|
||||
|
||||
static void OnGUI_Keys_Languages( string Key, ref TermData termdata, Localize localizeCmp, bool IsPrimaryKey, LanguageSourceData source )
|
||||
{
|
||||
//--[ Languages ]---------------------------
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
|
||||
OnGUI_Keys_LanguageTranslations(Key, localizeCmp, IsPrimaryKey, ref termdata, source);
|
||||
|
||||
if (termdata.TermType == eTermType.Text)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (TestButton(eTest_ActionType.Button_Term_TranslateAll, "Translate All", "Button", GUILayout.Width(85)))
|
||||
{
|
||||
var termData = termdata;
|
||||
GUITools.DelayedCall(() => TranslateLanguage( Key, termData, localizeCmp, source));
|
||||
GUI.FocusControl(string.Empty);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
OnGUI_TranslatingMessage();
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
static void TranslateLanguage( string Key, TermData termdata, Localize localizeCmp, LanguageSourceData source)
|
||||
{
|
||||
ClearErrors();
|
||||
string mainText = localizeCmp == null ? LanguageSourceData.GetKeyFromFullTerm(Key) : localizeCmp.GetMainTargetsText();
|
||||
|
||||
for (int i = 0; i < source.mLanguages.Count; ++i)
|
||||
if (source.mLanguages[i].IsEnabled() && string.IsNullOrEmpty(termdata.Languages[i]))
|
||||
{
|
||||
var langIdx = i;
|
||||
var term = termdata;
|
||||
var i2source = source;
|
||||
Translate(mainText, ref termdata, source.mLanguages[i].Code,
|
||||
(translation, error) =>
|
||||
{
|
||||
if (error != null)
|
||||
ShowError(error);
|
||||
else
|
||||
if (translation != null)
|
||||
{
|
||||
term.Languages[langIdx] = translation; //SetTranslation(langIdx, translation);
|
||||
i2source.Editor_SetDirty();
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnGUI_TranslatingMessage()
|
||||
{
|
||||
if (GoogleTranslation.IsTranslating())
|
||||
{
|
||||
// Connection Status Bar
|
||||
int time = (int)(Time.realtimeSinceStartup % 2 * 2.5);
|
||||
string Loading = "Translating" + ".....".Substring(0, time);
|
||||
GUI.color = Color.gray;
|
||||
GUILayout.BeginHorizontal(LocalizeInspector.GUIStyle_OldTextArea);
|
||||
GUILayout.Label(Loading, EditorStyles.miniLabel);
|
||||
GUI.color = Color.white;
|
||||
if (GUILayout.Button("Cancel", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
GoogleTranslation.CancelCurrentGoogleTranslations();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
HandleUtility.Repaint ();
|
||||
}
|
||||
}
|
||||
|
||||
static void OnGUI_Keys_Language_SpecializationsBar(TermData termData, LanguageSourceData source)
|
||||
{
|
||||
var activeSpecializations = termData.GetAllSpecializations();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
var TabStyle = new GUIStyle(GUI.skin.FindStyle("dragtab"));
|
||||
TabStyle.fixedHeight = 0;
|
||||
|
||||
//var ss = GUI.skin.FindStyle("TL tab left");
|
||||
var TabOpenStyle = new GUIStyle(GUI.skin.FindStyle("minibuttonmid"));
|
||||
TabOpenStyle.margin.right = -1;
|
||||
var TabCloseStyle = new GUIStyle(EditorStyles.label);
|
||||
//var TabCloseStyle = new GUIStyle(GUI.skin.FindStyle("TL tab right"));
|
||||
TabCloseStyle.margin.left = -1;
|
||||
TabCloseStyle.padding.left=4;
|
||||
|
||||
//-- Specialization Tabs -----
|
||||
|
||||
var prevSpecialization = "Any";
|
||||
foreach (var specialization in SpecializationManager.Singleton.mSpecializations)
|
||||
{
|
||||
if (!activeSpecializations.Contains(specialization) && specialization != GUI_SelectedSpecialization)
|
||||
continue;
|
||||
|
||||
bool isActive = specialization == GUI_SelectedSpecialization;
|
||||
var labelContent = new GUIContent(specialization, "Specialization of the main translation (i.e. variants that show only on specific platforms or devices)\nThis allows using 'tap' instead of 'click' for touch devices.");
|
||||
|
||||
if (isActive && activeSpecializations.Count>1)
|
||||
{
|
||||
GUILayout.BeginHorizontal(TabOpenStyle);
|
||||
GUILayout.Toggle(isActive, labelContent, TabStyle, GUILayout.Height(20), GUILayout.ExpandWidth(false));
|
||||
//GUILayout.Label(labelContent, TabOpenStyle);
|
||||
if (specialization != "Any" && GUILayout.Button("x", TabCloseStyle, GUILayout.Width(15)))
|
||||
{
|
||||
termData.RemoveSpecialization(specialization);
|
||||
GUI_SelectedSpecialization = prevSpecialization;
|
||||
GUI.FocusControl(null);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
else
|
||||
if (GUILayout.Toggle(isActive, labelContent, TabStyle, GUILayout.Height(25), GUILayout.ExpandWidth(false)) && !isActive)
|
||||
{
|
||||
GUI_SelectedSpecialization = specialization;
|
||||
GUI.FocusControl(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-- Add new Specialization -----
|
||||
int newIndex = EditorGUILayout.Popup(-1, SpecializationManager.Singleton.mSpecializations, "DropDown", GUILayout.Width(20));
|
||||
if (newIndex>=0)
|
||||
{
|
||||
string newSpecialization = SpecializationManager.Singleton.mSpecializations[newIndex];
|
||||
if (!activeSpecializations.Contains(newSpecialization))
|
||||
{
|
||||
for (int iLang = 0; iLang < source.mLanguages.Count; ++iLang)
|
||||
{
|
||||
string Translation = termData.GetTranslation(iLang, GUI_SelectedSpecialization, editMode: true);
|
||||
termData.SetTranslation(iLang, Translation, GUI_SelectedSpecialization);
|
||||
}
|
||||
GUI_SelectedSpecialization = newSpecialization;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
|
||||
GUI_ShowDisabledLanguagesTranslation = GUILayout.Toggle(GUI_ShowDisabledLanguagesTranslation, new GUIContent("L", "Show Disabled Languages"), "Button", GUILayout.ExpandWidth(false));
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(-3);
|
||||
}
|
||||
|
||||
static void OnGUI_Keys_LanguageTranslations (string Key, Localize localizeCmp, bool IsPrimaryKey, ref TermData termdata, LanguageSourceData source)
|
||||
{
|
||||
bool IsSelect = UnityEngine.Event.current.type==EventType.MouseUp;
|
||||
for (int i=0; i< source.mLanguages.Count; ++ i)
|
||||
{
|
||||
bool forcePreview = false;
|
||||
bool isEnabledLanguage = source.mLanguages[i].IsEnabled();
|
||||
|
||||
if (!isEnabledLanguage)
|
||||
{
|
||||
if (!GUI_ShowDisabledLanguagesTranslation)
|
||||
continue;
|
||||
GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, 0.35f);
|
||||
}
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
if (GUILayout.Button(source.mLanguages[i].Name, EditorStyles.label, GUILayout.Width(100)))
|
||||
forcePreview = true;
|
||||
|
||||
|
||||
string Translation = termdata.GetTranslation(i, GUI_SelectedSpecialization, editMode:true);
|
||||
if (Translation == null) Translation = string.Empty;
|
||||
|
||||
// if (termdata.Languages[i] != termdata.Languages_Touch[i] && !string.IsNullOrEmpty(termdata.Languages[i]) && !string.IsNullOrEmpty(termdata.Languages_Touch[i]))
|
||||
// GUI.contentColor = GUITools.LightYellow;
|
||||
|
||||
if (termdata.TermType == eTermType.Text || termdata.TermType==eTermType.Child)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck ();
|
||||
string CtrName = "TranslatedText"+i;
|
||||
GUI.SetNextControlName(CtrName);
|
||||
|
||||
EditPluralTranslations (ref Translation, i, source.mLanguages[i].Code);
|
||||
//Translation = EditorGUILayout.TextArea(Translation, Style_WrapTextField, GUILayout.Width(Screen.width - 260 - (autoTranslated ? 20 : 0)));
|
||||
if (EditorGUI.EndChangeCheck ())
|
||||
{
|
||||
termdata.SetTranslation(i, Translation, GUI_SelectedSpecialization);
|
||||
source.Editor_SetDirty();
|
||||
forcePreview = true;
|
||||
}
|
||||
|
||||
if (localizeCmp!=null &&
|
||||
(forcePreview || /*GUI.changed || */GUI.GetNameOfFocusedControl()==CtrName && IsSelect))
|
||||
{
|
||||
if (IsPrimaryKey && string.IsNullOrEmpty(localizeCmp.Term))
|
||||
{
|
||||
localizeCmp.mTerm = Key;
|
||||
}
|
||||
|
||||
if (!IsPrimaryKey && string.IsNullOrEmpty(localizeCmp.SecondaryTerm))
|
||||
{
|
||||
localizeCmp.mTermSecondary = Key;
|
||||
}
|
||||
|
||||
string PreviousLanguage = LocalizationManager.CurrentLanguage;
|
||||
LocalizationManager.PreviewLanguage(source.mLanguages[i].Name);
|
||||
if (forcePreview || IsSelect)
|
||||
LocalizationManager.LocalizeAll();
|
||||
else
|
||||
localizeCmp.OnLocalize(true);
|
||||
LocalizationManager.PreviewLanguage(PreviousLanguage);
|
||||
EditorUtility.SetDirty(localizeCmp);
|
||||
}
|
||||
GUI.contentColor = Color.white;
|
||||
|
||||
//if (autoTranslated)
|
||||
//{
|
||||
// if (GUILayout.Button(new GUIContent("\u2713"/*"A"*/,"Translated by Google Translator\nClick the button to approve the translation"), EditorStyles.toolbarButton, GUILayout.Width(autoTranslated ? 20 : 0)))
|
||||
// {
|
||||
// termdata.Flags[i] &= (byte)(byte.MaxValue ^ (byte)(GUI_SelectedSpecialization==0 ? TranslationFlag.AutoTranslated_Normal : TranslationFlag.AutoTranslated_Touch));
|
||||
// }
|
||||
//}
|
||||
|
||||
if (termdata.TermType == eTermType.Text)
|
||||
{
|
||||
if (TestButtonArg(eTest_ActionType.Button_Term_Translate, i, new GUIContent("T", "Translate"), EditorStyles.toolbarButton, GUILayout.Width(20)))
|
||||
{
|
||||
var termData = termdata;
|
||||
var indx = i;
|
||||
var key = Key;
|
||||
GUITools.DelayedCall(()=>TranslateTerm(key, termData, source, indx));
|
||||
GUI.FocusControl(string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string MultiSpriteName = string.Empty;
|
||||
|
||||
if (termdata.TermType==eTermType.Sprite && Translation.EndsWith("]", StringComparison.Ordinal)) // Handle sprites of type (Multiple): "SpritePath[SpriteName]"
|
||||
{
|
||||
int idx = Translation.LastIndexOf("[", StringComparison.Ordinal);
|
||||
int len = Translation.Length-idx-2;
|
||||
MultiSpriteName = Translation.Substring(idx+1, len);
|
||||
Translation = Translation.Substring(0, idx);
|
||||
}
|
||||
|
||||
Object Obj = null;
|
||||
|
||||
// Try getting the asset from the References section
|
||||
if (localizeCmp!=null)
|
||||
Obj = localizeCmp.FindTranslatedObject<Object>(Translation);
|
||||
if (Obj==null && source != null)
|
||||
Obj = source.FindAsset(Translation);
|
||||
|
||||
// If it wasn't in the references, Load it from Resources
|
||||
if (Obj==null && localizeCmp==null)
|
||||
Obj = ResourceManager.pInstance.LoadFromResources<Object>(Translation);
|
||||
|
||||
Type ObjType = typeof(Object);
|
||||
switch (termdata.TermType)
|
||||
{
|
||||
case eTermType.Font : ObjType = typeof(Font); break;
|
||||
case eTermType.Texture : ObjType = typeof(Texture); break;
|
||||
case eTermType.AudioClip : ObjType = typeof(AudioClip); break;
|
||||
case eTermType.GameObject : ObjType = typeof(GameObject); break;
|
||||
case eTermType.Sprite : ObjType = typeof(Sprite); break;
|
||||
case eTermType.Material : ObjType = typeof(Material); break;
|
||||
case eTermType.Mesh : ObjType = typeof(Mesh); break;
|
||||
#if NGUI
|
||||
case eTermType.UIAtlas : ObjType = typeof(UIAtlas); break;
|
||||
case eTermType.UIFont : ObjType = typeof(UIFont); break;
|
||||
#endif
|
||||
#if TK2D
|
||||
case eTermType.TK2dFont : ObjType = typeof(tk2dFont); break;
|
||||
case eTermType.TK2dCollection : ObjType = typeof(tk2dSpriteCollection); break;
|
||||
#endif
|
||||
|
||||
#if TextMeshPro
|
||||
case eTermType.TextMeshPFont : ObjType = typeof(TMP_FontAsset); break;
|
||||
#endif
|
||||
|
||||
#if SVG
|
||||
case eTermType.SVGAsset : ObjType = typeof(SVGImporter.SVGAsset); break;
|
||||
#endif
|
||||
|
||||
case eTermType.Object : ObjType = typeof(Object); break;
|
||||
}
|
||||
|
||||
if (Obj!=null && !string.IsNullOrEmpty(MultiSpriteName))
|
||||
{
|
||||
string sPath = AssetDatabase.GetAssetPath(Obj);
|
||||
Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath(sPath);
|
||||
Obj = null;
|
||||
for (int j=0, jmax=objs.Length; j<jmax; ++j)
|
||||
if (objs[j].name.Equals(MultiSpriteName))
|
||||
{
|
||||
Obj = objs[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool bShowTranslationLabel = Obj==null && !string.IsNullOrEmpty(Translation);
|
||||
if (bShowTranslationLabel)
|
||||
{
|
||||
GUI.backgroundColor=GUITools.DarkGray;
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
GUILayout.Space(2);
|
||||
|
||||
GUI.backgroundColor = Color.white;
|
||||
}
|
||||
|
||||
Object NewObj = EditorGUILayout.ObjectField(Obj, ObjType, true, GUILayout.ExpandWidth(true));
|
||||
if (Obj!=NewObj)
|
||||
{
|
||||
string sPath = null;
|
||||
if (NewObj != null)
|
||||
{
|
||||
sPath = AssetDatabase.GetAssetPath(NewObj);
|
||||
|
||||
mCurrentInspector.serializedObject.ApplyModifiedProperties();
|
||||
foreach (var cmp in mCurrentInspector.serializedObject.targetObjects)
|
||||
{
|
||||
AddObjectPath(ref sPath, cmp as Localize, NewObj);
|
||||
}
|
||||
mCurrentInspector.serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (HasObjectInReferences(NewObj, localizeCmp))
|
||||
sPath = NewObj.name;
|
||||
else
|
||||
if (termdata.TermType == eTermType.Sprite)
|
||||
sPath += "[" + NewObj.name + "]";
|
||||
}
|
||||
|
||||
termdata.SetTranslation(i, sPath, GUI_SelectedSpecialization);
|
||||
source.Editor_SetDirty();
|
||||
}
|
||||
|
||||
if (bShowTranslationLabel)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUI.color = Color.red;
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label (Translation, EditorStyles.miniLabel);
|
||||
GUILayout.FlexibleSpace();
|
||||
GUI.color = Color.white;
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
private static void TranslateTerm(string Key, TermData termdata, LanguageSourceData source, int i)
|
||||
{
|
||||
string sourceText = null;
|
||||
string sourceLangCode = null;
|
||||
FindTranslationSource(Key, termdata, source.mLanguages[i].Code, null, out sourceText, out sourceLangCode);
|
||||
|
||||
var term = termdata;
|
||||
var specialization = GUI_SelectedSpecialization;
|
||||
var langIdx = i;
|
||||
var i2source = source;
|
||||
Translate(sourceText, ref termdata, source.mLanguages[i].Code, (translation, error) =>
|
||||
{
|
||||
term.SetTranslation(langIdx, translation, specialization);
|
||||
i2source.Editor_SetDirty();
|
||||
}, specialization);
|
||||
}
|
||||
|
||||
static void EditPluralTranslations( ref string translation, int langIdx, string langCode )
|
||||
{
|
||||
bool hasParameters = false;
|
||||
int paramStart = translation.IndexOf("{[");
|
||||
hasParameters = paramStart >= 0 && translation.IndexOf ("]}", paramStart) > 0;
|
||||
|
||||
if (mShowPlural == langIdx && string.IsNullOrEmpty (translation))
|
||||
mShowPlural = -1;
|
||||
|
||||
bool allowPlural = hasParameters || translation.Contains("[i2p_");
|
||||
|
||||
if (allowPlural)
|
||||
{
|
||||
if (GUILayout.Toggle (mShowPlural == langIdx, "", EditorStyles.foldout, GUILayout.Width (13)))
|
||||
mShowPlural = langIdx;
|
||||
else if (mShowPlural == langIdx)
|
||||
mShowPlural = -1;
|
||||
|
||||
GUILayout.Space (-5);
|
||||
}
|
||||
|
||||
string finalTranslation = "";
|
||||
bool unfolded = mShowPlural == langIdx;
|
||||
bool isPlural = allowPlural && translation.Contains("[i2p_");
|
||||
if (unfolded)
|
||||
GUILayout.BeginVertical ("Box");
|
||||
|
||||
ShowPluralTranslation("Plural", langCode, translation, ref finalTranslation, true, unfolded, unfolded|isPlural );
|
||||
ShowPluralTranslation("Zero", langCode, translation, ref finalTranslation, unfolded, true, true );
|
||||
ShowPluralTranslation("One", langCode, translation, ref finalTranslation, unfolded, true, true );
|
||||
ShowPluralTranslation("Two", langCode, translation, ref finalTranslation, unfolded, true, true );
|
||||
ShowPluralTranslation("Few", langCode, translation, ref finalTranslation, unfolded, true, true );
|
||||
ShowPluralTranslation("Many", langCode, translation, ref finalTranslation, unfolded, true, true );
|
||||
|
||||
if (unfolded)
|
||||
GUILayout.EndVertical ();
|
||||
|
||||
translation = finalTranslation;
|
||||
}
|
||||
|
||||
static void ShowPluralTranslation(string pluralType, string langCode, string translation, ref string finalTranslation, bool show, bool allowDelete, bool showTag )
|
||||
{
|
||||
string tag = "[i2p_" + pluralType + "]";
|
||||
int idx0 = translation.IndexOf (tag, StringComparison.OrdinalIgnoreCase);
|
||||
bool hasTranslation = idx0 >= 0 || pluralType=="Plural";
|
||||
if (idx0 < 0) idx0 = 0;
|
||||
else idx0 += tag.Length;
|
||||
|
||||
int idx1 = translation.IndexOf ("[i2p_", idx0, StringComparison.OrdinalIgnoreCase);
|
||||
if (idx1 < 0) idx1 = translation.Length;
|
||||
|
||||
var pluralTranslation = translation.Substring(idx0, idx1-idx0);
|
||||
var newTrans = pluralTranslation;
|
||||
|
||||
bool allowPluralForm = GoogleLanguages.LanguageHasPluralType (langCode, pluralType);
|
||||
|
||||
if (hasTranslation && !allowPluralForm) {
|
||||
newTrans = "";
|
||||
GUI.changed = true;
|
||||
}
|
||||
|
||||
if (show && allowPluralForm)
|
||||
{
|
||||
if (!hasTranslation)
|
||||
GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, 0.35f);
|
||||
|
||||
GUILayout.BeginHorizontal ();
|
||||
if (showTag)
|
||||
GUILayout.Label (pluralType, EditorStyles.miniLabel, GUILayout.Width(35));
|
||||
newTrans = EditorGUILayout.TextArea (pluralTranslation, Style_WrapTextField);
|
||||
|
||||
if (allowDelete && GUILayout.Button("X", EditorStyles.toolbarButton, GUILayout.Width(15)))
|
||||
{
|
||||
newTrans = string.Empty;
|
||||
GUI.changed = true;
|
||||
GUIUtility.keyboardControl = 0;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal ();
|
||||
if (!hasTranslation)
|
||||
GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, 1);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty (newTrans))
|
||||
{
|
||||
if (hasTranslation || newTrans != pluralTranslation)
|
||||
{
|
||||
if (pluralType != "Plural")
|
||||
finalTranslation += tag;
|
||||
finalTranslation += newTrans;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*static public int DrawTranslationTabs( int Index )
|
||||
{
|
||||
GUIStyle MyStyle = new GUIStyle(GUI.skin.FindStyle("dragtab"));
|
||||
MyStyle.fixedHeight=0;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
for (int i=0; i<Tabs.Length; ++i)
|
||||
{
|
||||
if ( GUILayout.Toggle(Index==i, Tabs[i], MyStyle, GUILayout.Height(height)) && Index!=i)
|
||||
Index=i;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
return Index;
|
||||
}*/
|
||||
|
||||
static bool HasObjectInReferences( Object obj, Localize localizeCmp )
|
||||
{
|
||||
if (localizeCmp!=null && localizeCmp.TranslatedObjects.Contains(obj))
|
||||
return true;
|
||||
|
||||
if (mLanguageSource!=null && mLanguageSource.Assets.Contains(obj))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void AddObjectPath( ref string sPath, Localize localizeCmp, Object NewObj )
|
||||
{
|
||||
if (I2Utils.RemoveResourcesPath (ref sPath))
|
||||
return;
|
||||
|
||||
// If its not in the Resources folder and there is no object reference already in the
|
||||
// Reference array, then add that to the Localization component or the Language Source
|
||||
if (HasObjectInReferences(NewObj, localizeCmp))
|
||||
return;
|
||||
|
||||
if (localizeCmp!=null)
|
||||
{
|
||||
localizeCmp.AddTranslatedObject(NewObj);
|
||||
EditorUtility.SetDirty(localizeCmp);
|
||||
}
|
||||
else
|
||||
if (mLanguageSource!=null)
|
||||
{
|
||||
mLanguageSource.AddAsset(NewObj);
|
||||
mLanguageSource.Editor_SetDirty();
|
||||
}
|
||||
}
|
||||
|
||||
static void Translate ( string Key, ref TermData termdata, string TargetLanguageCode, GoogleTranslation.fnOnTranslated onTranslated, string overrideSpecialization )
|
||||
{
|
||||
#if UNITY_WEBPLAYER
|
||||
ShowError ("Contacting google translation is not yet supported on WebPlayer" );
|
||||
#else
|
||||
|
||||
if (!GoogleTranslation.CanTranslate())
|
||||
{
|
||||
ShowError ("WebService is not set correctly or needs to be reinstalled");
|
||||
return;
|
||||
}
|
||||
|
||||
// Translate first language that has something
|
||||
// If no language found, translation will fallback to autodetect language from key
|
||||
|
||||
string sourceCode, sourceText;
|
||||
FindTranslationSource( Key, termdata, TargetLanguageCode, overrideSpecialization, out sourceText, out sourceCode );
|
||||
GoogleTranslation.Translate( sourceText, sourceCode, TargetLanguageCode, onTranslated );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void FindTranslationSource( string Key, TermData termdata, string TargetLanguageCode, string forceSpecialization, out string sourceText, out string sourceLanguageCode )
|
||||
{
|
||||
sourceLanguageCode = "auto";
|
||||
sourceText = Key;
|
||||
|
||||
for (int i = 0, imax = termdata.Languages.Length; i < imax; ++i)
|
||||
{
|
||||
if (mLanguageSource.mLanguages[i].IsEnabled() && !string.IsNullOrEmpty(termdata.Languages[i]))
|
||||
{
|
||||
sourceText = forceSpecialization==null ? termdata.Languages[i] : termdata.GetTranslation(i, forceSpecialization, editMode:true);
|
||||
if (mLanguageSource.mLanguages[i].Code != TargetLanguageCode)
|
||||
{
|
||||
sourceLanguageCode = mLanguageSource.mLanguages[i].Code;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3efc8937ee2fcab49a6b6c1c9a1ed051
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
|
||||
#region Variables
|
||||
|
||||
Vector2 mScrollPos_BuildScenes = Vector2.zero;
|
||||
|
||||
static List<string> mSelectedScenes = new List<string>();
|
||||
|
||||
public enum eToolsMode { Parse, Categorize, Merge, NoLocalized, Script, CharSet }
|
||||
public eToolsMode mCurrentToolsMode = eToolsMode.Parse;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI
|
||||
|
||||
void OnGUI_Tools( bool reset )
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
eToolsMode OldMode = mCurrentToolsMode;
|
||||
mCurrentToolsMode = (eToolsMode)GUITools.DrawShadowedTabs ((int)mCurrentToolsMode, new[]{"Parse", "Categorize", "Merge", "No Localized", "Script", "CharSet"}, 30);
|
||||
if (mCurrentToolsMode != OldMode || reset)
|
||||
{
|
||||
ClearErrors();
|
||||
if (mCurrentToolsMode == eToolsMode.Script)
|
||||
SelectTermsFromScriptLocalization();
|
||||
OnGUI_ScenesList_SelectAllScenes(true);
|
||||
}
|
||||
|
||||
switch (mCurrentToolsMode)
|
||||
{
|
||||
case eToolsMode.Parse : OnGUI_Tools_ParseTerms(); break;
|
||||
case eToolsMode.Categorize : OnGUI_Tools_Categorize(); break;
|
||||
case eToolsMode.Merge : OnGUI_Tools_MergeTerms(); break;
|
||||
case eToolsMode.NoLocalized : OnGUI_Tools_NoLocalized(); break;
|
||||
case eToolsMode.Script : OnGUI_Tools_Script(); break;
|
||||
case eToolsMode.CharSet : OnGUI_Tools_CharSet(); break;
|
||||
}
|
||||
OnGUI_ShowMsg();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fa4621ebd4134e1989b73eb3f7b864f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
|
||||
Vector2 mScrollPos_CategorizedKeys = Vector2.zero;
|
||||
string mNewCategory = string.Empty;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI
|
||||
|
||||
void OnGUI_Tools_Categorize()
|
||||
{
|
||||
OnGUI_ScenesList(true);
|
||||
|
||||
GUI.backgroundColor = Color.Lerp (Color.gray, Color.white, 0.2f);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
GUI.backgroundColor = Color.white;
|
||||
GUILayout.Space (5);
|
||||
|
||||
EditorGUILayout.HelpBox("This tool changes the category of the selected Terms and updates the highlighted scenes", MessageType.Info);
|
||||
|
||||
GUILayout.Space (5);
|
||||
GUITools.CloseHeader();
|
||||
|
||||
OnGUI_Tools_Categorize_Terms();
|
||||
OnGUI_NewOrExistingCategory();
|
||||
}
|
||||
|
||||
void OnGUI_Tools_Categorize_Terms()
|
||||
{
|
||||
GUILayout.Label("Change Category of the following Terms:", EditorStyles.toolbarButton, GUILayout.ExpandWidth(true));
|
||||
|
||||
GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
|
||||
mScrollPos_CategorizedKeys = GUILayout.BeginScrollView( mScrollPos_CategorizedKeys, LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height ( 100));
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
if (mSelectedKeys.Count==0)
|
||||
{
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
//GUILayout.BeginVertical();
|
||||
EditorGUILayout.HelpBox("No Terms has been selected", MessageType.Warning);
|
||||
/*if (GUILayout.Button("Select Terms", EditorStyles.toolbarButton, GUILayout.ExpandWidth(true)))
|
||||
mCurrentViewMode = eViewMode.Keys;*/
|
||||
//GUILayout.EndVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
else
|
||||
{
|
||||
bool DoubleColumn = mSelectedKeys.Count>5;
|
||||
int HalfCount = Mathf.CeilToInt(mSelectedKeys.Count/2.0f);
|
||||
|
||||
for (int i=0, imax=mSelectedKeys.Count; i<imax; ++i)
|
||||
{
|
||||
if (DoubleColumn && i>=HalfCount) break;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
OnGUI_CategorizedTerm(mSelectedKeys[i]);
|
||||
|
||||
if (DoubleColumn && i+HalfCount<mSelectedKeys.Count)
|
||||
OnGUI_CategorizedTerm(mSelectedKeys[i+HalfCount]);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
void OnGUI_CategorizedTerm( string Term )
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
string sKey, sCategory;
|
||||
LanguageSourceData.DeserializeFullTerm(Term, out sKey, out sCategory);
|
||||
if (!string.IsNullOrEmpty(sCategory))
|
||||
{
|
||||
GUI.color = Color.gray;
|
||||
GUILayout.Label(sCategory+"/");
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
GUILayout.Label(sKey);
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void OnGUI_NewOrExistingCategory()
|
||||
{
|
||||
//--[ Create Category ]------------------------
|
||||
GUILayout.BeginHorizontal();
|
||||
mNewCategory = GUILayout.TextField(mNewCategory, EditorStyles.toolbarTextField, GUILayout.ExpandWidth(true));
|
||||
if (GUILayout.Button("Create", "toolbarbutton", GUILayout.Width(60)))
|
||||
{
|
||||
EditorApplication.update += AssignCategoryToSelectedTerms;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
//--[ Existing Category ]------------------------
|
||||
int Index = 0;
|
||||
List<string> Categories = LocalizationManager.GetCategories();
|
||||
|
||||
for (int i=0, imax=Categories.Count; i<imax; ++i)
|
||||
if (Categories[i].ToLower().Contains(mNewCategory.ToLower()))
|
||||
{
|
||||
Index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
int NewIndex = EditorGUILayout.Popup(Index, Categories.ToArray(), EditorStyles.toolbarPopup, GUILayout.ExpandWidth(true));
|
||||
if (NewIndex!=Index)
|
||||
mNewCategory = Categories[ NewIndex ];
|
||||
if (GUILayout.Button("Use", "toolbarbutton", GUILayout.Width(60)))
|
||||
{
|
||||
mNewCategory = Categories[ NewIndex ];
|
||||
EditorApplication.update += AssignCategoryToSelectedTerms;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Assigning Category
|
||||
|
||||
public static Dictionary<string, string> TermReplacements;
|
||||
|
||||
void AssignCategoryToSelectedTerms()
|
||||
{
|
||||
mIsParsing = true;
|
||||
|
||||
EditorApplication.update -= AssignCategoryToSelectedTerms;
|
||||
|
||||
mNewCategory = mNewCategory.Trim (LanguageSourceData.CategorySeparators);
|
||||
|
||||
if (mNewCategory==LanguageSourceData.EmptyCategory)
|
||||
mNewCategory = string.Empty;
|
||||
|
||||
TermReplacements = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
for (int i=mSelectedKeys.Count-1; i>=0; --i)
|
||||
{
|
||||
string sKey, sCategory;
|
||||
string OldTerm = mSelectedKeys[i];
|
||||
|
||||
LanguageSourceData.DeserializeFullTerm( OldTerm, out sKey, out sCategory );
|
||||
if (!string.IsNullOrEmpty(mNewCategory))
|
||||
sKey = string.Concat(mNewCategory, "/", sKey);
|
||||
|
||||
if (OldTerm == sKey)
|
||||
continue;
|
||||
|
||||
TermReplacements[ OldTerm ] = sKey;
|
||||
if (!mLanguageSource.ContainsTerm(sKey))
|
||||
{
|
||||
TermData termData = mLanguageSource.GetTermData( OldTerm );
|
||||
if (termData != null)
|
||||
termData.Term = sKey;
|
||||
else
|
||||
TermReplacements.Remove (OldTerm);
|
||||
mLanguageSource.Editor_SetDirty();
|
||||
}
|
||||
}
|
||||
if (TermReplacements.Count<=0)
|
||||
{
|
||||
ShowError ("Unable to assign category: Terms were not found in the selected LanguageSource");
|
||||
}
|
||||
else
|
||||
{
|
||||
mLanguageSource.UpdateDictionary(true);
|
||||
ExecuteActionOnSelectedScenes( ReplaceTermsInCurrentScene );
|
||||
ParseTerms(true, false, true);
|
||||
|
||||
if (string.IsNullOrEmpty(mNewCategory))
|
||||
mNewCategory = LanguageSourceData.EmptyCategory;
|
||||
if (!mSelectedCategories.Contains(mNewCategory))
|
||||
mSelectedCategories.Add (mNewCategory);
|
||||
//RemoveUnusedCategoriesFromSelected();
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
}
|
||||
TermReplacements = null;
|
||||
mIsParsing = false;
|
||||
}
|
||||
|
||||
public static void ReplaceTermsInCurrentScene()
|
||||
{
|
||||
Localize[] Locals = (Localize[])Resources.FindObjectsOfTypeAll(typeof(Localize));
|
||||
|
||||
if (Locals==null)
|
||||
return;
|
||||
|
||||
bool changed = false;
|
||||
for (int i=0, imax=Locals.Length; i<imax; ++i)
|
||||
{
|
||||
Localize localize = Locals[i];
|
||||
if (localize==null || localize.gameObject==null || !GUITools.ObjectExistInScene(localize.gameObject))
|
||||
continue;
|
||||
|
||||
string NewTerm;
|
||||
if (TermReplacements.TryGetValue(localize.Term, out NewTerm))
|
||||
{
|
||||
localize.mTerm = NewTerm;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (TermReplacements.TryGetValue(localize.SecondaryTerm, out NewTerm))
|
||||
{
|
||||
localize.mTermSecondary = NewTerm;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
Editor_SaveScene(true);
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 690f28955e250544a9bfaf741e4cced7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,190 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
|
||||
List<string> mCharSetTool_Languages = new List<string>();
|
||||
string mCharSet = string.Empty;
|
||||
bool mCharSetTool_CaseSensitive;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI Generate Script
|
||||
|
||||
void OnGUI_Tools_CharSet()
|
||||
{
|
||||
bool computeSet = false;
|
||||
|
||||
// remove missing languages
|
||||
for (int i=mCharSetTool_Languages.Count-1; i>=0; --i)
|
||||
{
|
||||
if (mLanguageSource.GetLanguageIndex(mCharSetTool_Languages[i])<0)
|
||||
mCharSetTool_Languages.RemoveAt(i);
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal (EditorStyles.toolbar);
|
||||
GUILayout.Label ("Languages:", EditorStyles.miniLabel, GUILayout.ExpandWidth(true));
|
||||
if (GUILayout.Button ("All", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
mCharSetTool_Languages.Clear ();
|
||||
mCharSetTool_Languages.AddRange (mLanguageSource.mLanguages.Select(x=>x.Name));
|
||||
computeSet = true;
|
||||
}
|
||||
if (GUILayout.Button ("None", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
mCharSetTool_Languages.Clear ();
|
||||
computeSet = true;
|
||||
}
|
||||
if (GUILayout.Button ("Invert", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
var current = mCharSetTool_Languages.ToList ();
|
||||
mCharSetTool_Languages.Clear ();
|
||||
mCharSetTool_Languages.AddRange (mLanguageSource.mLanguages.Select(x=>x.Name).Where(j=>!current.Contains(j)));
|
||||
computeSet = true;
|
||||
}
|
||||
|
||||
|
||||
GUILayout.EndHorizontal ();
|
||||
|
||||
//--[ Language List ]--------------------------
|
||||
|
||||
GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
|
||||
mScrollPos_Languages = GUILayout.BeginScrollView( mScrollPos_Languages, LocalizeInspector.GUIStyle_OldTextArea, GUILayout.MinHeight (100), GUILayout.MaxHeight(Screen.height), GUILayout.ExpandHeight(false));
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
for (int i=0, imax=mLanguageSource.mLanguages.Count; i<imax; ++i)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
var language = mLanguageSource.mLanguages[i].Name;
|
||||
bool hasLanguage = mCharSetTool_Languages.Contains(language);
|
||||
bool newValue = GUILayout.Toggle (hasLanguage, "", "OL Toggle", GUILayout.ExpandWidth(false));
|
||||
GUILayout.Label(language);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (hasLanguage != newValue)
|
||||
{
|
||||
if (newValue)
|
||||
mCharSetTool_Languages.Add(language);
|
||||
else
|
||||
mCharSetTool_Languages.Remove(language);
|
||||
|
||||
computeSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
|
||||
//GUILayout.Space (5);
|
||||
|
||||
GUI.backgroundColor = Color.Lerp (Color.gray, Color.white, 0.2f);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
EditorGUILayout.HelpBox("This tool shows all characters used in the selected languages", MessageType.Info);
|
||||
|
||||
GUILayout.Space (5);
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUI.changed = false;
|
||||
mCharSetTool_CaseSensitive = GUILayout.Toggle(mCharSetTool_CaseSensitive, "Case-Sensitive", GUILayout.ExpandWidth(false));
|
||||
if (GUI.changed)
|
||||
computeSet = true;
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space (5);
|
||||
|
||||
if (computeSet)
|
||||
UpdateCharSets();
|
||||
|
||||
int numUsedChars = string.IsNullOrEmpty (mCharSet) ? 0 : mCharSet.Length;
|
||||
GUILayout.Label ("Used Characters: (" + numUsedChars+")");
|
||||
EditorGUILayout.TextArea (mCharSet ?? "");
|
||||
GUILayout.BeginHorizontal ();
|
||||
GUILayout.FlexibleSpace ();
|
||||
if (GUILayout.Button ("Copy To Clipboard", GUITools.DontExpandWidth))
|
||||
EditorGUIUtility.systemCopyBuffer = mCharSet;
|
||||
GUILayout.EndHorizontal ();
|
||||
GUILayout.EndVertical ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Generate Char Set
|
||||
|
||||
void UpdateCharSets ()
|
||||
{
|
||||
mCharSet = "";
|
||||
var sb = new HashSet<char> ();
|
||||
var LanIndexes = new List<int> ();
|
||||
for (int i=0; i<mLanguageSource.mLanguages.Count; ++i)
|
||||
if (mCharSetTool_Languages.Contains(mLanguageSource.mLanguages[i].Name))
|
||||
LanIndexes.Add(i);
|
||||
|
||||
foreach (var termData in mLanguageSource.mTerms)
|
||||
{
|
||||
for (int i=0; i<LanIndexes.Count; ++i)
|
||||
{
|
||||
int iLanguage = LanIndexes[i];
|
||||
bool isRTL = LocalizationManager.IsRTL( mLanguageSource.mLanguages[iLanguage].Code );
|
||||
AppendToCharSet( sb, termData.Languages[iLanguage], isRTL );
|
||||
}
|
||||
}
|
||||
var bytes = Encoding.UTF8.GetBytes( sb.ToArray().OrderBy(c => c).ToArray() );
|
||||
mCharSet = Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
|
||||
void AppendToCharSet( HashSet<char> sb, string text, bool isRTL )
|
||||
{
|
||||
if (string.IsNullOrEmpty (text))
|
||||
return;
|
||||
|
||||
text = RemoveTagsPrefix(text, "[i2p_");
|
||||
text = RemoveTagsPrefix(text, "[i2s_");
|
||||
|
||||
if (isRTL)
|
||||
text = RTLFixer.Fix( text );
|
||||
|
||||
foreach (char c in text)
|
||||
{
|
||||
if (!mCharSetTool_CaseSensitive)
|
||||
{
|
||||
sb.Add(char.ToLowerInvariant(c));
|
||||
sb.Add(char.ToUpperInvariant(c));
|
||||
}
|
||||
else
|
||||
sb.Add(c);
|
||||
}
|
||||
}
|
||||
|
||||
// Given "[i2p_" it removes all tags that start with that (e.g. [i2p_Zero] [i2p_One], etc)
|
||||
string RemoveTagsPrefix(string text, string tagPrefix)
|
||||
{
|
||||
int idx = 0;
|
||||
while (idx < text.Length)
|
||||
{
|
||||
idx = text.IndexOf(tagPrefix);
|
||||
if (idx < 0)
|
||||
break;
|
||||
|
||||
int idx2 = text.IndexOf(']', idx);
|
||||
if (idx2 < 0)
|
||||
break;
|
||||
|
||||
text = text.Remove(idx, idx2 - idx+1);
|
||||
}
|
||||
return text;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 104713279df05ac4b96f5a76ab621c8a
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI
|
||||
|
||||
void OnGUI_Tools_MergeTerms()
|
||||
{
|
||||
OnGUI_ScenesList(true);
|
||||
|
||||
GUI.backgroundColor = Color.Lerp (Color.gray, Color.white, 0.2f);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
GUI.backgroundColor = Color.white;
|
||||
GUILayout.Space (5);
|
||||
|
||||
EditorGUILayout.HelpBox("This option replace all occurrences of this key in the selected scenes", MessageType.Info);
|
||||
|
||||
GUILayout.Space (5);
|
||||
GUITools.CloseHeader();
|
||||
|
||||
OnGUI_Tools_Categorize_Terms();
|
||||
OnGUI_NewOrExistingTerm();
|
||||
}
|
||||
|
||||
void OnGUI_NewOrExistingTerm()
|
||||
{
|
||||
if (mKeyToExplore==null)
|
||||
mKeyToExplore = string.Empty;
|
||||
|
||||
GUI.backgroundColor = Color.Lerp (Color.gray, Color.white, 0.2f);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
GUI.backgroundColor = Color.white;
|
||||
GUILayout.Space(5);
|
||||
GUILayout.Label("Replace By:");
|
||||
GUILayout.EndVertical();
|
||||
|
||||
//--[ Create Term ]------------------------
|
||||
GUILayout.BeginHorizontal();
|
||||
mKeyToExplore = GUILayout.TextField(mKeyToExplore, EditorStyles.toolbarTextField, GUILayout.ExpandWidth(true));
|
||||
if (GUILayout.Button("Create", "toolbarbutton", GUILayout.Width(60)))
|
||||
{
|
||||
LanguageSourceData.ValidateFullTerm( ref mKeyToExplore );
|
||||
EditorApplication.update += ReplaceSelectedTerms;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
//--[ Existing Term ]------------------------
|
||||
int Index = 0;
|
||||
List<string> Terms = mLanguageSource.GetTermsList();
|
||||
|
||||
for (int i=0, imax=Terms.Count; i<imax; ++i)
|
||||
if (Terms[i].ToLower().Contains(mKeyToExplore.ToLower()))
|
||||
{
|
||||
Index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
int NewIndex = EditorGUILayout.Popup(Index, Terms.ToArray(), EditorStyles.toolbarPopup, GUILayout.ExpandWidth(true));
|
||||
if (NewIndex != Index)
|
||||
{
|
||||
SelectTerm (Terms [NewIndex]);
|
||||
ClearErrors();
|
||||
}
|
||||
if (GUILayout.Button("Use", "toolbarbutton", GUILayout.Width(60)))
|
||||
{
|
||||
SelectTerm( Terms[ NewIndex ] );
|
||||
EditorApplication.update += ReplaceSelectedTerms;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Merge Terms
|
||||
|
||||
void ReplaceSelectedTerms()
|
||||
{
|
||||
EditorApplication.update -= ReplaceSelectedTerms;
|
||||
if (string.IsNullOrEmpty(mKeyToExplore))
|
||||
return;
|
||||
|
||||
mIsParsing = true;
|
||||
string sNewKey = mKeyToExplore;
|
||||
|
||||
//--[ Create new Term ]-----------------------
|
||||
if (mLanguageSource.GetTermData(sNewKey)==null)
|
||||
{
|
||||
TermData termData = AddLocalTerm(sNewKey);
|
||||
|
||||
//--[ Copy the values from any existing term if the target is a new term
|
||||
TermData oldTerm = null;
|
||||
for (int i=0, imax=mSelectedKeys.Count; i<imax; ++i)
|
||||
{
|
||||
oldTerm = mLanguageSource.GetTermData(mSelectedKeys[i]);
|
||||
if (oldTerm!=null) break;
|
||||
}
|
||||
|
||||
if (oldTerm!=null)
|
||||
{
|
||||
termData.TermType = oldTerm.TermType;
|
||||
termData.Description = oldTerm.Description;
|
||||
Array.Copy(oldTerm.Languages, termData.Languages, oldTerm.Languages.Length);
|
||||
}
|
||||
}
|
||||
|
||||
//--[ Delete the selected Terms from the source ]-----------------
|
||||
TermReplacements = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
for (int i=mSelectedKeys.Count-1; i>=0; --i)
|
||||
{
|
||||
string OldTerm = mSelectedKeys[i];
|
||||
if (OldTerm == sNewKey)
|
||||
continue;
|
||||
|
||||
TermReplacements[ OldTerm ] = mKeyToExplore;
|
||||
DeleteTerm(OldTerm);
|
||||
}
|
||||
ExecuteActionOnSelectedScenes( ReplaceTermsInCurrentScene );
|
||||
DoParseTermsInCurrentScene();
|
||||
|
||||
//--[ Update Selected Categories ]-------------
|
||||
string mNewCategory = LanguageSourceData.GetCategoryFromFullTerm(sNewKey);
|
||||
if (mNewCategory == string.Empty)
|
||||
mNewCategory = LanguageSourceData.EmptyCategory;
|
||||
if (!mSelectedCategories.Contains(mNewCategory))
|
||||
mSelectedCategories.Add (mNewCategory);
|
||||
//RemoveUnusedCategoriesFromSelected();
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
TermReplacements = null;
|
||||
mIsParsing = false;
|
||||
}
|
||||
|
||||
void RemoveUnusedCategoriesFromSelected()
|
||||
{
|
||||
List<string> Categories = LocalizationManager.GetCategories();
|
||||
for (int i=mSelectedCategories.Count-1; i>=0; --i)
|
||||
if (!Categories.Contains( mSelectedCategories[i] ))
|
||||
mSelectedCategories.RemoveAt(i);
|
||||
|
||||
if (mSelectedCategories.Count == 0)
|
||||
mSelectedCategories.AddRange(Categories);
|
||||
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d59fa53e0df75a34693c4673bba5ed94
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,163 @@
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
static string _Tools_NoLocalized_Include,
|
||||
_Tools_NoLocalized_Exclude;
|
||||
const string _Help_Tool_NoLocalized = "This selects all labels in the current scene that don't have a Localized component.\n\nWhen Include or Exclude are set, labels will be filtered based on those settings.Separate by (,) if multiple strings are used.\n(e.g. Include:\"example,tutorial\")";
|
||||
#endregion
|
||||
|
||||
#region GUI Find NoLocalized Terms
|
||||
|
||||
void OnGUI_Tools_NoLocalized()
|
||||
{
|
||||
//OnGUI_ScenesList();
|
||||
|
||||
if (_Tools_NoLocalized_Include==null)
|
||||
{
|
||||
_Tools_NoLocalized_Include = EditorPrefs.GetString ("_Tools_NoLocalized_Include", string.Empty);
|
||||
_Tools_NoLocalized_Exclude = EditorPrefs.GetString ("_Tools_NoLocalized_Exclude", string.Empty);
|
||||
}
|
||||
|
||||
GUILayout.Space (5);
|
||||
|
||||
GUI.backgroundColor = Color.Lerp (Color.gray, Color.white, 0.2f);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
EditorGUILayout.HelpBox(_Help_Tool_NoLocalized, MessageType.Info);
|
||||
|
||||
GUILayout.Space(5);
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label ("Include:", GUILayout.Width(60));
|
||||
_Tools_NoLocalized_Include = EditorGUILayout.TextArea(_Tools_NoLocalized_Include, GUILayout.ExpandWidth(true));
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label ("Exclude:", GUILayout.Width(60));
|
||||
_Tools_NoLocalized_Exclude = EditorGUILayout.TextArea(_Tools_NoLocalized_Exclude, GUILayout.ExpandWidth(true));
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space (5);
|
||||
|
||||
GUILayout.BeginHorizontal ();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Select No Localized Labels"))
|
||||
EditorApplication.update += SelectNoLocalizedLabels;
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Find No Localized
|
||||
|
||||
void SelectNoLocalizedLabels()
|
||||
{
|
||||
EditorPrefs.SetString ("_Tools_NoLocalized_Include", _Tools_NoLocalized_Include);
|
||||
EditorPrefs.SetString ("_Tools_NoLocalized_Exclude", _Tools_NoLocalized_Exclude);
|
||||
|
||||
EditorApplication.update -= SelectNoLocalizedLabels;
|
||||
|
||||
List<Component> labels = new List<Component>();
|
||||
|
||||
TextMesh[] textMeshes = (TextMesh[])Resources.FindObjectsOfTypeAll(typeof(TextMesh));
|
||||
if (textMeshes!=null && textMeshes.Length>0)
|
||||
labels.AddRange(textMeshes);
|
||||
|
||||
#if NGUI
|
||||
UILabel[] uiLabels = (UILabel[])Resources.FindObjectsOfTypeAll(typeof(UILabel));
|
||||
if (uiLabels!=null && uiLabels.Length>0)
|
||||
labels.AddRange(uiLabels);
|
||||
#endif
|
||||
Text[] uiTexts = (Text[])Resources.FindObjectsOfTypeAll(typeof(Text));
|
||||
if (uiTexts!=null && uiTexts.Length>0)
|
||||
labels.AddRange(uiTexts);
|
||||
#if TextMeshPro
|
||||
TextMeshPro[] tmpText = (TextMeshPro[])Resources.FindObjectsOfTypeAll(typeof(TextMeshPro));
|
||||
if (tmpText!=null && tmpText.Length>0)
|
||||
labels.AddRange(tmpText);
|
||||
|
||||
TextMeshProUGUI[] uiTextsUGUI = (TextMeshProUGUI[])Resources.FindObjectsOfTypeAll(typeof(TextMeshProUGUI));
|
||||
if (uiTextsUGUI!=null && uiTextsUGUI.Length>0)
|
||||
labels.AddRange(uiTextsUGUI);
|
||||
#endif
|
||||
#if TK2D
|
||||
tk2dTextMesh[] tk2dTM = (tk2dTextMesh[])Resources.FindObjectsOfTypeAll(typeof(tk2dTextMesh));
|
||||
if (tk2dTM!=null && tk2dTM.Length>0)
|
||||
labels.AddRange(tk2dTM);
|
||||
#endif
|
||||
|
||||
if (labels.Count==0)
|
||||
return;
|
||||
|
||||
string[] Includes = null;
|
||||
string[] Excludes = null;
|
||||
|
||||
if (!string.IsNullOrEmpty (_Tools_NoLocalized_Include))
|
||||
Includes = _Tools_NoLocalized_Include.ToLower().Split(',', ';');
|
||||
|
||||
if (!string.IsNullOrEmpty (_Tools_NoLocalized_Exclude))
|
||||
Excludes = _Tools_NoLocalized_Exclude.ToLower().Split(',', ';');
|
||||
|
||||
List<GameObject> Objs = new List<GameObject>();
|
||||
|
||||
for (int i=0, imax=labels.Count; i<imax; ++i)
|
||||
{
|
||||
Component label = labels[i];
|
||||
if (label==null || label.gameObject==null || !GUITools.ObjectExistInScene(label.gameObject))
|
||||
continue;
|
||||
|
||||
if (labels[i].GetComponent<Localize>()!=null)
|
||||
continue;
|
||||
|
||||
if (ShouldFilter(label.name.ToLower(), Includes, Excludes))
|
||||
continue;
|
||||
|
||||
Objs.Add( labels[i].gameObject );
|
||||
}
|
||||
|
||||
if (Objs.Count>0)
|
||||
Selection.objects = Objs.ToArray();
|
||||
else
|
||||
ShowWarning("All labels in this scene have a Localize component assigned");
|
||||
}
|
||||
|
||||
bool ShouldFilter( string Text, string[] Includes, string[] Excludes )
|
||||
{
|
||||
if (Includes!=null && Includes.Length>0)
|
||||
{
|
||||
bool hasAny = false;
|
||||
for (int j=0; j<Includes.Length; ++j)
|
||||
if (Text.Contains(Includes[j]))
|
||||
{
|
||||
hasAny = true;
|
||||
break;
|
||||
}
|
||||
if (!hasAny)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Excludes!=null && Excludes.Length>0)
|
||||
{
|
||||
for (int j=0; j<Excludes.Length; ++j)
|
||||
if (Text.Contains(Excludes[j]))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18d48e525beac1e4baff73e509fc246d
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,378 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public class ParsedTerm
|
||||
{
|
||||
public string Category, Term, FullTerm;
|
||||
public int Usage;
|
||||
public TermData termData;
|
||||
}
|
||||
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
|
||||
public static SortedDictionary<string, ParsedTerm> mParsedTerms = new SortedDictionary<string, ParsedTerm>(StringComparer.Ordinal); // All Terms resulted from parsing the scenes and collecting the Localize.Term and how many times the terms are used
|
||||
public static HashSet<string> mParsedCategories = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
public static List<ParsedTerm> mShowableTerms = new List<ParsedTerm> (); // this contains the terms from mParsedTerms that should be shown in the list (filtered by search string, usage, etc)
|
||||
public static bool mParseTermsIn_Scenes = true;
|
||||
public static bool mParseTermsIn_Scripts = true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI Parse Keys
|
||||
|
||||
void OnGUI_Tools_ParseTerms()
|
||||
{
|
||||
OnGUI_ScenesList();
|
||||
|
||||
GUI.backgroundColor = Color.Lerp (Color.gray, Color.white, 0.2f);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
GUILayout.Space (5);
|
||||
|
||||
EditorGUILayout.HelpBox("This tool searches all Terms used in the selected scenes and updates the usage counter in the Terms Tab", MessageType.Info);
|
||||
|
||||
GUILayout.Space (5);
|
||||
|
||||
GUILayout.BeginHorizontal ();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.BeginHorizontal ("Box");
|
||||
mParseTermsIn_Scenes = GUILayout.Toggle(mParseTermsIn_Scenes, new GUIContent("Parse SCENES", "Opens the selected scenes and finds all the used terms"));
|
||||
GUILayout.FlexibleSpace();
|
||||
mParseTermsIn_Scripts = GUILayout.Toggle(mParseTermsIn_Scripts, new GUIContent("Parse SCRIPTS", "Searches all .cs files and counts all terms like: ScriptLocalization.Get(\"xxx\")"));
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal ();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Parse Localized Terms"))
|
||||
{
|
||||
EditorApplication.update += ParseTermsInSelectedScenes;
|
||||
if (mParseTermsIn_Scripts)
|
||||
EditorApplication.update += ParseTermsInScripts;
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Parsed Terms Handlers
|
||||
|
||||
public static ParsedTerm GetParsedTerm( string Term )
|
||||
{
|
||||
ParsedTerm data;
|
||||
if (!mParsedTerms.TryGetValue(Term, out data))
|
||||
data = AddParsedTerm(Term, null, null, 0);
|
||||
return data;
|
||||
}
|
||||
|
||||
static ParsedTerm AddParsedTerm( string FullTerm, string TermKey, string Category, int Usage )
|
||||
{
|
||||
if (TermKey==null)
|
||||
LanguageSourceData.DeserializeFullTerm(FullTerm, out TermKey, out Category);
|
||||
|
||||
var data = new ParsedTerm();
|
||||
data.Usage = Usage;
|
||||
data.FullTerm = FullTerm;
|
||||
data.Term = TermKey;
|
||||
data.Category = Category;
|
||||
|
||||
mParsedTerms[FullTerm] = data;
|
||||
return data;
|
||||
}
|
||||
|
||||
public static void RemoveParsedTerm( string Term )
|
||||
{
|
||||
mParsedTerms.Remove(Term);
|
||||
}
|
||||
|
||||
public static void DecreaseParsedTerm( string Term )
|
||||
{
|
||||
ParsedTerm data = GetParsedTerm(Term);
|
||||
data.Usage = Mathf.Max (0, data.Usage-1);
|
||||
}
|
||||
|
||||
static void UpdateParsedCategories()
|
||||
{
|
||||
mParsedCategories.Clear();
|
||||
mParsedCategories.UnionWith( mParsedTerms.Select(x=>x.Value.Category) );
|
||||
|
||||
mSelectedCategories.RemoveAll(x=>!mParsedCategories.Contains(x));
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ParseKeys
|
||||
|
||||
public static void ParseTermsInSelectedScenes()
|
||||
{
|
||||
EditorApplication.update -= ParseTermsInSelectedScenes;
|
||||
ParseTerms(false, false, true);
|
||||
}
|
||||
|
||||
public static void DoParseTermsInCurrentScene()
|
||||
{
|
||||
EditorApplication.update -= DoParseTermsInCurrentScene;
|
||||
ParseTerms(true, false, true);
|
||||
}
|
||||
|
||||
public static void DoParseTermsInCurrentSceneAndScripts()
|
||||
{
|
||||
EditorApplication.update -= DoParseTermsInCurrentSceneAndScripts;
|
||||
ParseTerms(true, true, true);
|
||||
}
|
||||
|
||||
static void ParseTerms(bool OnlyCurrentScene, bool ParseScripts, bool OpenTermsTab)
|
||||
{
|
||||
mIsParsing = true;
|
||||
|
||||
mParsedTerms.Clear();
|
||||
mSelectedKeys.Clear();
|
||||
mParsedCategories.Clear();
|
||||
|
||||
if (ParseScripts)
|
||||
{
|
||||
ParseTermsInScripts();
|
||||
FindTermsInLocalizedStrings();
|
||||
}
|
||||
|
||||
if (mParseTermsIn_Scenes)
|
||||
{
|
||||
if (!OnlyCurrentScene)
|
||||
ExecuteActionOnSelectedScenes(FindTermsInCurrentScene);
|
||||
else
|
||||
FindTermsInCurrentScene();
|
||||
}
|
||||
|
||||
FindTermsNotUsed();
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
|
||||
|
||||
if (mParsedTerms.Count <= 0)
|
||||
{
|
||||
ShowInfo("No terms where found during parsing");
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateParsedCategories();
|
||||
{
|
||||
mSelectedCategories.Clear();
|
||||
mSelectedCategories.AddRange(mParsedCategories);
|
||||
}
|
||||
|
||||
|
||||
if (mLanguageSource!=null)
|
||||
{
|
||||
var sourceCategories = mLanguageSource.GetCategories();
|
||||
mSelectedCategories.RemoveAll(x => !sourceCategories.Contains(x));
|
||||
}
|
||||
|
||||
if (OpenTermsTab)
|
||||
{
|
||||
if ((mFlagsViewKeys & (int)eFlagsViewKeys.Missing) > 0)
|
||||
{
|
||||
mFlagsViewKeys = (int)eFlagsViewKeys.Used | (int)eFlagsViewKeys.NotUsed | (int)eFlagsViewKeys.Missing;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFlagsViewKeys = (int)eFlagsViewKeys.Used | (int)eFlagsViewKeys.NotUsed;
|
||||
}
|
||||
mCurrentViewMode = eViewMode.Keys;
|
||||
}
|
||||
mIsParsing = false;
|
||||
}
|
||||
|
||||
static void FindTermsInCurrentScene()
|
||||
{
|
||||
Localize[] Locals = (Localize[])Resources.FindObjectsOfTypeAll(typeof(Localize));
|
||||
|
||||
if (Locals==null)
|
||||
return;
|
||||
|
||||
for (int i=0, imax=Locals.Length; i<imax; ++i)
|
||||
{
|
||||
Localize localize = Locals[i];
|
||||
if (localize==null || localize.Source!=null && localize.Source.SourceData!=mLanguageSource || localize.gameObject==null || !GUITools.ObjectExistInScene(localize.gameObject))
|
||||
continue;
|
||||
|
||||
string Term, SecondaryTerm;
|
||||
//Term = localize.Term;
|
||||
//SecondaryTerm = localize.SecondaryTerm;
|
||||
localize.GetFinalTerms( out Term, out SecondaryTerm );
|
||||
|
||||
if (!string.IsNullOrEmpty(Term))
|
||||
GetParsedTerm(Term).Usage++;
|
||||
|
||||
if (!string.IsNullOrEmpty(SecondaryTerm))
|
||||
GetParsedTerm(SecondaryTerm).Usage++;
|
||||
}
|
||||
}
|
||||
|
||||
static void FindTermsInLocalizedStrings()
|
||||
{
|
||||
MonoBehaviour[] behaviors = (MonoBehaviour[])Resources.FindObjectsOfTypeAll(typeof(MonoBehaviour));
|
||||
Type Type_localizedString = typeof(LocalizedString);
|
||||
foreach (var cmp in behaviors)
|
||||
{
|
||||
if (cmp.GetType().Name.Contains("Example_LocalizedString"))
|
||||
continue;
|
||||
|
||||
var props = cmp.GetType()
|
||||
.GetProperties()
|
||||
.Where(x=> Type_localizedString.IsAssignableFrom(x.PropertyType) ||
|
||||
Attribute.IsDefined(x, typeof(TermsPopup)));
|
||||
foreach (var p in props)
|
||||
{
|
||||
string value = null;
|
||||
if (Type_localizedString.IsAssignableFrom(p.PropertyType))
|
||||
{
|
||||
var varObj = p.GetValue(cmp,null);
|
||||
value = Convert.ToString(varObj.GetType().GetField("mTerm").GetValue(varObj));
|
||||
}
|
||||
else
|
||||
{
|
||||
value = Convert.ToString(p.GetValue(cmp,null));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
GetParsedTerm(value).Usage++;
|
||||
}
|
||||
|
||||
//Debug.LogFormat("{0} ({1})", p.Name, p.PropertyType);
|
||||
//Debug.Log(value);
|
||||
}
|
||||
|
||||
|
||||
var variables = cmp.GetType()
|
||||
.GetFields()
|
||||
.Where(x => Type_localizedString.IsAssignableFrom(x.FieldType) ||
|
||||
Attribute.IsDefined(x, typeof(TermsPopup)));
|
||||
foreach (var v in variables)
|
||||
{
|
||||
string value = null;
|
||||
if (Type_localizedString.IsAssignableFrom(v.FieldType))
|
||||
{
|
||||
var varObj = v.GetValue(cmp);
|
||||
value = Convert.ToString(varObj.GetType().GetField("mTerm").GetValue(varObj));
|
||||
}
|
||||
else
|
||||
{
|
||||
value = Convert.ToString(v.GetValue(cmp));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
GetParsedTerm(value).Usage++;
|
||||
}
|
||||
//Debug.LogFormat("{0} ({1})", v.Name, v.FieldType);
|
||||
//Debug.Log(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FindTermsNotUsed()
|
||||
{
|
||||
// every Term that is in the DB but not in mParsedTerms
|
||||
if (mLanguageSource == null)
|
||||
return;
|
||||
|
||||
//string lastCategory = null;
|
||||
foreach (TermData termData in mLanguageSource.mTerms)
|
||||
GetParsedTerm(termData.Term);
|
||||
}
|
||||
|
||||
static void ParseTermsInScripts()
|
||||
{
|
||||
EditorApplication.update -= ParseTermsInScripts;
|
||||
|
||||
string[] scriptFiles = AssetDatabase.GetAllAssetPaths().Where(path => path.ToLower().EndsWith(".cs")).ToArray();
|
||||
|
||||
string mLocalizationManager = @"GetTranslation\s?\(\s?\""(.*?)\""";
|
||||
string mLocalizationManagerOld = @"GetTermTranslation\s?\(\s?\""(.*?)\""";
|
||||
string mLocalizationManagerTry = @"TryGetTranslation\s?\(\s?\""(.*?)\""";
|
||||
string mSetTerm = @"SetTerm\s?\(\s?\""(.*?)\""";
|
||||
|
||||
Regex regex = new Regex(mLocalizationManager + "|" + mLocalizationManagerTry + "|" + mLocalizationManagerOld + "|" + mSetTerm, RegexOptions.Multiline);
|
||||
|
||||
foreach (string scriptFile in scriptFiles)
|
||||
{
|
||||
string scriptContents = File.ReadAllText(scriptFile);
|
||||
MatchCollection matches = regex.Matches(scriptContents);
|
||||
for (int matchNum = 0; matchNum < matches.Count; matchNum++)
|
||||
{
|
||||
Match match = matches[matchNum];
|
||||
string term = I2Utils.GetCaptureMatch(match);
|
||||
GetParsedTerm(term).Usage++;
|
||||
}
|
||||
}
|
||||
ScheduleUpdateTermsToShowInList();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Misc
|
||||
|
||||
public static void SetAllTerms_When_InferredTerms_IsInSource()
|
||||
{
|
||||
var Locals = Resources.FindObjectsOfTypeAll(typeof(Localize)) as Localize[];
|
||||
|
||||
if (Locals==null)
|
||||
return;
|
||||
|
||||
foreach (var localize in Locals)
|
||||
{
|
||||
if (localize == null || localize.Source != null && localize.Source.SourceData != mLanguageSource || localize.gameObject == null || !GUITools.ObjectExistInScene (localize.gameObject))
|
||||
continue;
|
||||
|
||||
if (!string.IsNullOrEmpty (localize.mTerm) && !string.IsNullOrEmpty (localize.SecondaryTerm))
|
||||
continue;
|
||||
|
||||
ApplyInferredTerm( localize );
|
||||
}
|
||||
|
||||
ParseTerms (true, false, true);
|
||||
}
|
||||
|
||||
public static void ApplyInferredTerm( Localize localize)
|
||||
{
|
||||
if (mLanguageSource==null)
|
||||
return;
|
||||
if (!string.IsNullOrEmpty (localize.mTerm) && !string.IsNullOrEmpty (localize.mTermSecondary))
|
||||
return;
|
||||
|
||||
string sTerm, sSecTerm;
|
||||
localize.GetFinalTerms (out sTerm, out sSecTerm);
|
||||
|
||||
if (string.IsNullOrEmpty (localize.mTerm))
|
||||
{
|
||||
var termData = mLanguageSource.GetTermData (sTerm, true);
|
||||
if (termData!=null)
|
||||
localize.mTerm = termData.Term;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty (localize.mTermSecondary))
|
||||
{
|
||||
var termData = mLanguageSource.GetTermData (sSecTerm, true);
|
||||
if (termData!=null)
|
||||
localize.mTermSecondary = termData.Term;
|
||||
}
|
||||
|
||||
//localize.Source = mLanguageSource;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 697e1bc5d373845df927c0da625b7cad
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
EditorBuildSettingsScene[] mScenesInBuildSettings;
|
||||
bool Tools_ShowScenesList;
|
||||
#endregion
|
||||
|
||||
#region GUI
|
||||
|
||||
void OnGUI_ScenesList( bool SmallSize = false )
|
||||
{
|
||||
mScenesInBuildSettings = EditorBuildSettings.scenes;
|
||||
string currentScene = Editor_GetCurrentScene ();
|
||||
|
||||
List<string> sceneList = mScenesInBuildSettings.Select(x=>x.path).ToList();
|
||||
if (!sceneList.Contains (currentScene))
|
||||
sceneList.Insert (0, currentScene);
|
||||
|
||||
mSelectedScenes.RemoveAll (x => !sceneList.Contains(x));
|
||||
if (mSelectedScenes.Count==0)
|
||||
mSelectedScenes.Add (currentScene);
|
||||
|
||||
if (!Tools_ShowScenesList)
|
||||
{
|
||||
GUILayout.Space(5);
|
||||
GUILayout.BeginHorizontal();
|
||||
Tools_ShowScenesList = GUILayout.Toggle(Tools_ShowScenesList, "", EditorStyles.foldout, GUILayout.ExpandWidth(false));
|
||||
|
||||
string sceneText = string.Empty;
|
||||
if (mSelectedScenes.Count==1 && mSelectedScenes[0]== currentScene)
|
||||
sceneText = "Current Scene";
|
||||
else
|
||||
sceneText = string.Format("{0} of {1} Scenes", mSelectedScenes.Count, Mathf.Max(mScenesInBuildSettings.Length, mSelectedScenes.Count));
|
||||
var stl = new GUIStyle("toolbarbutton");
|
||||
stl.richText = true;
|
||||
if (GUILayout.Button("Scenes to Parse: <i>"+sceneText+"</i>", stl))
|
||||
Tools_ShowScenesList = true;
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(10);
|
||||
return;
|
||||
}
|
||||
OnGUI_ScenesList_TitleBar();
|
||||
|
||||
GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
|
||||
mScrollPos_BuildScenes = GUILayout.BeginScrollView( mScrollPos_BuildScenes, LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height ( SmallSize ? 100 : 200));
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
for (int i=0, imax=sceneList.Count; i<imax; ++i)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
OnGUI_SelectableToogleListItem( sceneList[i], ref mSelectedScenes, "OL Toggle" );
|
||||
|
||||
bool bSelected = mSelectedScenes.Contains(sceneList[i]);
|
||||
GUI.color = bSelected ? Color.white : Color.Lerp(Color.gray, Color.white, 0.5f);
|
||||
|
||||
string scenePath = sceneList[i];
|
||||
if (scenePath.StartsWith("assets/", StringComparison.OrdinalIgnoreCase))
|
||||
scenePath = scenePath.Substring("Assets/".Length);
|
||||
|
||||
if (currentScene == sceneList[i])
|
||||
scenePath = "[Current Scene] " + scenePath;
|
||||
|
||||
if (GUILayout.Button (scenePath, "Label"))
|
||||
{
|
||||
if (mSelectedScenes.Contains(sceneList[i]))
|
||||
mSelectedScenes.Remove(sceneList[i]);
|
||||
else
|
||||
mSelectedScenes.Add(sceneList[i]);
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
void OnGUI_ScenesList_TitleBar()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
Tools_ShowScenesList = GUILayout.Toggle(Tools_ShowScenesList, "", EditorStyles.foldout, GUILayout.ExpandWidth(false));
|
||||
|
||||
if (GUILayout.Button("Scenes to Parse:", "toolbarbutton"))
|
||||
Tools_ShowScenesList = false;
|
||||
|
||||
if (GUILayout.Button("All", "toolbarbutton", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
OnGUI_ScenesList_SelectAllScenes(false);
|
||||
}
|
||||
if (GUILayout.Button("None", "toolbarbutton", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
mSelectedScenes.Clear();
|
||||
}
|
||||
if (GUILayout.Button("Used", "toolbarbutton", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
mSelectedScenes.Clear();
|
||||
for (int i=0, imax=mScenesInBuildSettings.Length; i<imax; ++i)
|
||||
if (mScenesInBuildSettings[i].enabled)
|
||||
mSelectedScenes.Add (mScenesInBuildSettings[i].path);
|
||||
}
|
||||
if (GUILayout.Button("Current", "toolbarbutton", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
mSelectedScenes.Clear();
|
||||
mSelectedScenes.Add (Editor_GetCurrentScene());
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
private void OnGUI_ScenesList_SelectAllScenes(bool reset)
|
||||
{
|
||||
if (reset || mScenesInBuildSettings == null)
|
||||
{
|
||||
mScenesInBuildSettings = EditorBuildSettings.scenes;
|
||||
}
|
||||
|
||||
mSelectedScenes.Clear();
|
||||
for (int i = 0, imax = mScenesInBuildSettings.Length; i < imax; ++i)
|
||||
mSelectedScenes.Add(mScenesInBuildSettings[i].path);
|
||||
if (!mSelectedScenes.Contains(Editor_GetCurrentScene()))
|
||||
mSelectedScenes.Add(Editor_GetCurrentScene());
|
||||
}
|
||||
|
||||
void SelectUsedScenes()
|
||||
{
|
||||
mSelectedScenes.Clear();
|
||||
for (int i=0, imax=mScenesInBuildSettings.Length; i<imax; ++i)
|
||||
if (mScenesInBuildSettings[i].enabled)
|
||||
mSelectedScenes.Add( mScenesInBuildSettings[i].path );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Iterate thru the Scenes
|
||||
|
||||
delegate void Delegate0();
|
||||
|
||||
static void ExecuteActionOnSelectedScenes( Delegate0 Action )
|
||||
{
|
||||
string InitialScene = Editor_GetCurrentScene();
|
||||
|
||||
if (mSelectedScenes.Count<=0)
|
||||
mSelectedScenes.Add (InitialScene);
|
||||
|
||||
bool HasSaved = false;
|
||||
|
||||
foreach (string ScenePath in mSelectedScenes)
|
||||
{
|
||||
if (ScenePath != Editor_GetCurrentScene())
|
||||
{
|
||||
if (!HasSaved) // Saving the initial scene to avoid loosing changes
|
||||
{
|
||||
Editor_SaveScene ();
|
||||
HasSaved = true;
|
||||
}
|
||||
Editor_OpenScene( ScenePath );
|
||||
}
|
||||
|
||||
Action();
|
||||
}
|
||||
|
||||
if (InitialScene != Editor_GetCurrentScene())
|
||||
Editor_OpenScene( InitialScene );
|
||||
|
||||
if (mLanguageSource!=null)
|
||||
Selection.activeObject = mLanguageSource.ownerObject;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26e06d7fb9cef5341a791b25339444e0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,281 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngineInternal;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
#region Variables
|
||||
|
||||
int Script_Tool_MaxVariableLength = 50;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI Generate Script
|
||||
|
||||
void OnGUI_Tools_Script()
|
||||
{
|
||||
OnGUI_KeysList (false, 200, false);
|
||||
|
||||
//GUILayout.Space (5);
|
||||
|
||||
GUI.backgroundColor = Color.Lerp (Color.gray, Color.white, 0.2f);
|
||||
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
EditorGUILayout.HelpBox("This tool creates the ScriptLocalization.cs with the selected terms.\nThis allows for Compile Time Checking on the used Terms referenced in scripts", MessageType.Info);
|
||||
|
||||
GUILayout.Space (5);
|
||||
|
||||
GUILayout.BeginHorizontal ();
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUIUtility.labelWidth = 240;
|
||||
EditorGUILayout.IntField("Max Length of the Generated Term IDs:", Script_Tool_MaxVariableLength);
|
||||
EditorGUIUtility.labelWidth = 0;
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space (10);
|
||||
|
||||
GUILayout.BeginHorizontal ();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(new GUIContent("Select Baked Terms", "Selects all the terms previously built in ScriptLocalization.cs")))
|
||||
SelectTermsFromScriptLocalization();
|
||||
|
||||
if (GUILayout.Button("Build Script with Selected Terms"))
|
||||
EditorApplication.update += BuildScriptWithSelectedTerms;
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
void SelectTermsFromScriptLocalization()
|
||||
{
|
||||
var ScriptFile = GetPathToGeneratedScriptLocalization();
|
||||
|
||||
try
|
||||
{
|
||||
var text = File.ReadAllText(ScriptFile, Encoding.UTF8);
|
||||
|
||||
mSelectedKeys.Clear();
|
||||
foreach (Match match in Regex.Matches(text, "\".+\""))
|
||||
{
|
||||
var term = match.Value.Substring(1, match.Value.Length - 2);
|
||||
|
||||
if (!mSelectedKeys.Contains(term))
|
||||
{
|
||||
mSelectedKeys.Add(term);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception)
|
||||
{ }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Generate Script File
|
||||
|
||||
void BuildScriptWithSelectedTerms()
|
||||
{
|
||||
EditorApplication.update -= BuildScriptWithSelectedTerms;
|
||||
var sbTrans = new StringBuilder();
|
||||
var sbTerms = new StringBuilder();
|
||||
sbTrans.AppendLine( "using UnityEngine;" );
|
||||
sbTrans.AppendLine();
|
||||
sbTrans.AppendLine( "namespace TEngine.Localization" );
|
||||
sbTrans.AppendLine( "{" );
|
||||
sbTrans.AppendLine( " public static class ScriptLocalization" );
|
||||
sbTrans.AppendLine( " {" );
|
||||
|
||||
|
||||
sbTerms.AppendLine();
|
||||
sbTerms.AppendLine(" public static class ScriptTerms");
|
||||
sbTerms.AppendLine(" {");
|
||||
|
||||
|
||||
|
||||
BuildScriptWithSelectedTerms( sbTrans, sbTerms );
|
||||
sbTrans.AppendLine(" }"); // Closing both classes
|
||||
sbTerms.AppendLine(" }");
|
||||
|
||||
|
||||
string ScriptFile = GetPathToGeneratedScriptLocalization ();
|
||||
Debug.Log ("Generating: " + ScriptFile);
|
||||
|
||||
var filePath = Application.dataPath + ScriptFile.Substring("Assets".Length);
|
||||
string fileText = sbTrans + sbTerms.ToString() + "}";
|
||||
|
||||
File.WriteAllText(filePath, fileText, Encoding.UTF8);
|
||||
|
||||
AssetDatabase.ImportAsset(ScriptFile);
|
||||
}
|
||||
|
||||
static string GetPathToGeneratedScriptLocalization()
|
||||
{
|
||||
string[] assets = AssetDatabase.FindAssets("ScriptLocalization");
|
||||
if (assets.Length>0)
|
||||
{
|
||||
try
|
||||
{
|
||||
string FilePath = AssetDatabase.GUIDToAssetPath(assets[0]);
|
||||
return FilePath;
|
||||
}
|
||||
catch(Exception)
|
||||
{ }
|
||||
}
|
||||
|
||||
return "Assets/ScriptLocalization.cs";
|
||||
}
|
||||
|
||||
void BuildScriptWithSelectedTerms( StringBuilder sbTrans, StringBuilder sbTerms )
|
||||
{
|
||||
List<string> Categories = LocalizationManager.GetCategories();
|
||||
foreach (string Category in Categories)
|
||||
{
|
||||
List<string> CategoryTerms = ScriptTool_GetSelectedTermsInCategory(Category);
|
||||
if (CategoryTerms.Count<=0)
|
||||
continue;
|
||||
|
||||
List<string> AdjustedCategoryTerms = new List<string>(CategoryTerms);
|
||||
for (int i=0, imax=AdjustedCategoryTerms.Count; i<imax; ++i)
|
||||
AdjustedCategoryTerms[i] = ScriptTool_AdjustTerm( AdjustedCategoryTerms[i] );
|
||||
ScriptTool_EnumerateDuplicatedTerms(AdjustedCategoryTerms);
|
||||
|
||||
sbTrans.AppendLine();
|
||||
sbTerms.AppendLine();
|
||||
if (Category != LanguageSourceData.EmptyCategory)
|
||||
{
|
||||
sbTrans.AppendLine(" public static class " + ScriptTool_AdjustTerm(Category,true));
|
||||
sbTrans.AppendLine(" {");
|
||||
|
||||
sbTerms.AppendLine(" public static class " + ScriptTool_AdjustTerm(Category, true));
|
||||
sbTerms.AppendLine(" {");
|
||||
}
|
||||
|
||||
BuildScriptCategory( sbTrans, sbTerms, Category, AdjustedCategoryTerms, CategoryTerms );
|
||||
|
||||
if (Category != LanguageSourceData.EmptyCategory)
|
||||
{
|
||||
sbTrans.AppendLine(" }");
|
||||
sbTerms.AppendLine(" }");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<string> ScriptTool_GetSelectedTermsInCategory( string Category )
|
||||
{
|
||||
List<string> list = new List<string>();
|
||||
foreach (string FullKey in mSelectedKeys)
|
||||
{
|
||||
string categ = LanguageSourceData.GetCategoryFromFullTerm(FullKey);
|
||||
if (categ == Category && ShouldShowTerm(FullKey))
|
||||
{
|
||||
list.Add( LanguageSourceData.GetKeyFromFullTerm(FullKey) );
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void BuildScriptCategory( StringBuilder sbTrans, StringBuilder sbTerms, string Category, List<string> AdjustedTerms, List<string> Terms )
|
||||
{
|
||||
if (Category==LanguageSourceData.EmptyCategory)
|
||||
{
|
||||
for (int i = 0; i < Terms.Count; ++i)
|
||||
{
|
||||
sbTrans.AppendLine( " public static string " + AdjustedTerms[i] + " \t\t{ get{ return LocalizationManager.GetTranslation (\"" + Terms[i] + "\"); } }");
|
||||
sbTerms.AppendLine(" public const string " + AdjustedTerms[i] + " = \"" + Terms[i] + "\";");
|
||||
}
|
||||
}
|
||||
else
|
||||
for (int i=0; i<Terms.Count; ++i)
|
||||
{
|
||||
sbTrans.AppendLine(" public static string "+AdjustedTerms[i]+ " \t\t{ get{ return LocalizationManager.GetTranslation (\"" + Category+"/"+Terms[i]+"\"); } }");
|
||||
sbTerms.AppendLine(" public const string " + AdjustedTerms[i] + " = \"" + Category + "/" + Terms[i] + "\";");
|
||||
}
|
||||
}
|
||||
|
||||
string ScriptTool_AdjustTerm( string Term, bool allowFullLength = false )
|
||||
{
|
||||
Term = I2Utils.GetValidTermName(Term);
|
||||
|
||||
// C# IDs can't start with a number
|
||||
if (I2Utils.NumberChars.IndexOf(Term[0])>=0)
|
||||
Term = "_"+Term;
|
||||
|
||||
if (!allowFullLength && Term.Length>Script_Tool_MaxVariableLength)
|
||||
Term = Term.Substring(0, Script_Tool_MaxVariableLength);
|
||||
|
||||
// Remove invalid characters
|
||||
char[] chars = Term.ToCharArray();
|
||||
for (int i=0, imax=chars.Length; i<imax; ++i)
|
||||
{
|
||||
if (!IsValidCharacter(chars[i]))
|
||||
chars[i] = '_';
|
||||
}
|
||||
|
||||
Term = new string(chars);
|
||||
if (IsCSharpKeyword(Term)) return string.Concat('@', Term);
|
||||
return Term;
|
||||
|
||||
bool IsValidCharacter(char c)
|
||||
{
|
||||
if (I2Utils.ValidChars.IndexOf(c)>=0) return true;
|
||||
return c>='\u4e00' && c<='\u9fff'; // Chinese/Japanese characters
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptTool_EnumerateDuplicatedTerms(List<string> AdjustedTerms)
|
||||
{
|
||||
string lastTerm = "$";
|
||||
int Counter = 1;
|
||||
for (int i=0, imax=AdjustedTerms.Count; i<imax; ++i)
|
||||
{
|
||||
string currentTerm = AdjustedTerms[i];
|
||||
if (lastTerm == currentTerm || i<imax-1 && currentTerm==AdjustedTerms[i+1])
|
||||
{
|
||||
AdjustedTerms[i] = AdjustedTerms[i] + "_" + Counter;
|
||||
Counter++;
|
||||
}
|
||||
else
|
||||
Counter = 1;
|
||||
|
||||
lastTerm = currentTerm;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
bool IsCSharpKeyword(string variableName)
|
||||
{
|
||||
return variableName == "abstract" || variableName == "as" || variableName == "base" || variableName == "bool" ||
|
||||
variableName == "break" || variableName == "byte" || variableName == "" || variableName == "case" ||
|
||||
variableName == "catch" || variableName == "char" || variableName == "checked" || variableName == "class" ||
|
||||
variableName == "const" || variableName == "continue" || variableName == "decimal" || variableName == "default" ||
|
||||
variableName == "delegate" || variableName == "do" || variableName == "double" || variableName == "else" ||
|
||||
variableName == "enum" || variableName == "event" || variableName == "explicit" || variableName == "extern" ||
|
||||
variableName == "false" || variableName == "finally" || variableName == "fixed" || variableName == "float" ||
|
||||
variableName == "for" || variableName == "foreach" || variableName == "goto" || variableName == "if" ||
|
||||
variableName == "implicit" || variableName == "in" || variableName == "int" || variableName == "interface" ||
|
||||
variableName == "internal" || variableName == "is" || variableName == "lock" || variableName == "long" ||
|
||||
variableName == "namespace" || variableName == "new" || variableName == "null" || variableName == "object" ||
|
||||
variableName == "operator" || variableName == "out" || variableName == "override" || variableName == "params" ||
|
||||
variableName == "private" || variableName == "protected" || variableName == "public" || variableName == "readonly" ||
|
||||
variableName == "ref" || variableName == "return" || variableName == "sbyte" || variableName == "sealed" ||
|
||||
variableName == "short" || variableName == "sizeof" || variableName == "stackalloc" || variableName == "static" ||
|
||||
variableName == "string" || variableName == "struct" || variableName == "switch" || variableName == "this" ||
|
||||
variableName == "throw" || variableName == "true" || variableName == "try" || variableName == "typeof" ||
|
||||
variableName == "uint" || variableName == "ulong" || variableName == "unchecked" || variableName == "unsafe" ||
|
||||
variableName == "short" || variableName == "using" || variableName == "virtual" || variableName == "void" ||
|
||||
variableName == "volatile" || variableName == "while";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 634a9cc818031dd4c8ddf451d36abe00
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public partial class LocalizationEditor
|
||||
{
|
||||
void OnGUI_Warning_SourceInScene()
|
||||
{
|
||||
// if (mLanguageSource.UserAgreesToHaveItOnTheScene) return;
|
||||
|
||||
// LanguageSourceData source = GetSourceData();
|
||||
// if (source.IsGlobalSource() && !GUITools.ObjectExistInScene(source.gameObject))
|
||||
// return;
|
||||
|
||||
// string Text = @"Its advised to only use the source in I2\Localization\Resources\I2Languages.prefab
|
||||
|
||||
//That works as a GLOBAL source accessible in ALL scenes. That’s why its recommended to add all your translations there.
|
||||
|
||||
//You don't need to instantiate that prefab into the scene, just click the prefab and add the Data.
|
||||
|
||||
//Only use Sources in the scene when the localization is meant to be ONLY used there.
|
||||
//However, that's not advised and is only used in the Examples to keep them separated from your project localization.
|
||||
|
||||
//Furthermore, having a source in the scene require that any Localize component get a reference to that source to work properly. By dragging the source into the field at the bottom of the Localize component.";
|
||||
// EditorGUILayout.HelpBox(Text, MessageType.Warning);
|
||||
|
||||
// GUILayout.BeginHorizontal();
|
||||
// GUILayout.FlexibleSpace();
|
||||
// if (GUILayout.Button("Keep as is"))
|
||||
// {
|
||||
// SerializedProperty Agree = serializedObject.FindProperty("UserAgreesToHaveItOnTheScene");
|
||||
// Agree.boolValue = true;
|
||||
// }
|
||||
|
||||
// GUILayout.FlexibleSpace();
|
||||
|
||||
// if (GUILayout.Button("Open the Global Source"))
|
||||
// {
|
||||
// GameObject Prefab = (Resources.Load(LocalizationManager.GlobalSources[0]) as GameObject);
|
||||
// Selection.activeGameObject = Prefab;
|
||||
// }
|
||||
|
||||
// GUILayout.FlexibleSpace();
|
||||
// if (GUILayout.Button("Delete this and open the Global Source"))
|
||||
// {
|
||||
// EditorApplication.CallbackFunction Callback = null;
|
||||
// EditorApplication.update += Callback = ()=>
|
||||
// {
|
||||
// EditorApplication.update -= Callback;
|
||||
|
||||
// if (source.GetComponents<Component>().Length<=2)
|
||||
// {
|
||||
// Debug.Log ("Deleting GameObject '" + source.name + "' and Openning the "+LocalizationManager.GlobalSources[0]+".prefab");
|
||||
// DestroyImmediate (source.gameObject);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Debug.Log ("Deleting the LanguageSource inside GameObject " + source.name + " and Openning the "+LocalizationManager.GlobalSources[0] +".prefab");
|
||||
// DestroyImmediate (source);
|
||||
// }
|
||||
|
||||
// GameObject Prefab = (Resources.Load(LocalizationManager.GlobalSources[0]) as GameObject);
|
||||
// Selection.activeGameObject = Prefab;
|
||||
// };
|
||||
// }
|
||||
// GUILayout.FlexibleSpace();
|
||||
// GUILayout.EndHorizontal();
|
||||
|
||||
// GUILayout.Space(10);
|
||||
}
|
||||
|
||||
private bool bSourceInsidePluginsFolder = true;
|
||||
public void OnGUI_Warning_SourceInsidePluginsFolder()
|
||||
{
|
||||
if (!bSourceInsidePluginsFolder || mLanguageSource.UserAgreesToHaveItInsideThePluginsFolder)
|
||||
return;
|
||||
|
||||
if (!mLanguageSource.IsGlobalSource())
|
||||
{
|
||||
bSourceInsidePluginsFolder = false;
|
||||
return;
|
||||
}
|
||||
|
||||
string pluginPath = UpgradeManager.GetI2LocalizationPath();
|
||||
string assetPath = AssetDatabase.GetAssetPath(target);
|
||||
|
||||
if (!assetPath.StartsWith(pluginPath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
bSourceInsidePluginsFolder = false;
|
||||
return;
|
||||
}
|
||||
|
||||
string Text = @"Its advised to move this Global Source to a folder outside the I2 Localization.
|
||||
For example (Assets/I2/Resources) instead of (Assets/I2/Localization/Resources)
|
||||
|
||||
That way upgrading the plugin its as easy as deleting the I2/Localization and I2/Common folders and reinstalling.
|
||||
|
||||
Do you want the plugin to automatically move the LanguageSource to a folder outside the plugin?";
|
||||
EditorGUILayout.HelpBox(Text, MessageType.Warning);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Keep as is"))
|
||||
{
|
||||
SerializedProperty Agree = serializedObject.FindProperty("UserAgreesToHaveItInsideThePluginsFolder");
|
||||
Agree.boolValue = true;
|
||||
bSourceInsidePluginsFolder = true;
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button("Ask me later"))
|
||||
{
|
||||
bSourceInsidePluginsFolder = false;
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Move to the Recommended Folder"))
|
||||
EditorApplication.delayCall += MoveGlobalSource;
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(10);
|
||||
}
|
||||
|
||||
public bool OnGUI_Warning_SourceNotUpToDate()
|
||||
{
|
||||
if (mProp_GoogleLiveSyncIsUptoDate.boolValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string Text = "Spreadsheet is not up-to-date and Google Live Synchronization is enabled\n\nWhen playing in the device the Spreadsheet will be downloaded and override the translations built from the editor.\n\nTo fix this, Import or Export REPLACE to Google";
|
||||
EditorGUILayout.HelpBox(Text, MessageType.Warning);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void MoveGlobalSource()
|
||||
{
|
||||
EditorApplication.delayCall -= MoveGlobalSource;
|
||||
|
||||
string pluginPath = UpgradeManager.GetI2LocalizationPath();
|
||||
string assetPath = AssetDatabase.GetAssetPath(mLanguageSource.ownerObject);
|
||||
|
||||
string I2Path = pluginPath.Substring(0, pluginPath.Length-"/Localization".Length);
|
||||
string newPath = I2Path + "/Resources/" + mLanguageSource.ownerObject.name + ".prefab";
|
||||
|
||||
string fullresFolder = Application.dataPath + I2Path.Replace("Assets","") + "/Resources";
|
||||
bool folderExists = Directory.Exists (fullresFolder);
|
||||
|
||||
if (!folderExists)
|
||||
AssetDatabase.CreateFolder(I2Path, "Resources");
|
||||
AssetDatabase.MoveAsset(assetPath, newPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
var prefab = AssetDatabase.LoadAssetAtPath(newPath, typeof(GameObject)) as GameObject;
|
||||
Selection.activeGameObject = prefab;
|
||||
|
||||
Debug.Log("LanguageSource moved to:" + newPath);
|
||||
ShowInfo("Please, ignore some console warnings/errors produced by this operation, everything worked fine. In a new release those warnings will be cleared");
|
||||
}
|
||||
|
||||
public static void DelayedDestroySource()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20e86d3a806624846bccd81bac9f935f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,151 @@
|
||||
#if UNITY_ANDROID
|
||||
using UnityEditor.Callbacks;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Android;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public class PostProcessBuild_Android
|
||||
#if UNITY_2021_1_OR_NEWER
|
||||
: IPostGenerateGradleAndroidProject
|
||||
#endif
|
||||
{
|
||||
#if UNITY_2021_1_OR_NEWER
|
||||
|
||||
public int callbackOrder => 0;
|
||||
public void OnPostGenerateGradleAndroidProject(string path)
|
||||
{
|
||||
path = Path.Combine(path, "src/main");
|
||||
PostProcessAndroid(BuildTarget.Android, path);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Post Process Scene is a hack, because using PostProcessBuild will be called after the APK is generated, and so, I didn't find a way to copy the new files
|
||||
[PostProcessScene]
|
||||
public static void OnPostProcessScene()
|
||||
{
|
||||
// #if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
|
||||
// bool isFirstScene = (EditorBuildSettings.scenes.Length>0 && EditorBuildSettings.scenes[0].path == EditorApplication.currentScene);
|
||||
// #else
|
||||
// bool isFirstScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex <= 0;
|
||||
// #endif
|
||||
//
|
||||
// if (!EditorApplication.isPlayingOrWillChangePlaymode &&
|
||||
// (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android) &&
|
||||
// isFirstScene)
|
||||
// {
|
||||
// string projPath = System.IO.Path.GetFullPath(Application.streamingAssetsPath + "/../../Temp/StagingArea");
|
||||
// //string projPath = System.IO.Path.GetFullPath(Application.dataPath+ "/Plugins/Android");
|
||||
// PostProcessAndroid(BuildTarget.Android, projPath);
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//[PostProcessBuild(10000)]
|
||||
public static void PostProcessAndroid(BuildTarget buildTarget, string pathToBuiltProject)
|
||||
{
|
||||
if (buildTarget!=BuildTarget.Android)
|
||||
return;
|
||||
|
||||
if (LocalizationManager.Sources.Count <= 0)
|
||||
LocalizationManager.UpdateSources();
|
||||
|
||||
// Get language with variants, but also add it without the variant to allow fallbacks (e.g. en-CA also adds en)
|
||||
var langCodes = LocalizationManager.GetAllLanguagesCode(false).Concat( LocalizationManager.GetAllLanguagesCode(true) ).Distinct().ToList();
|
||||
|
||||
if (langCodes.Count <= 0)
|
||||
return;
|
||||
string stringXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"+
|
||||
"<resources>\n"+
|
||||
" <string name=\"app_name\">{0}</string>\n"+
|
||||
"</resources>";
|
||||
|
||||
SetStringsFile( pathToBuiltProject+"/res/values", "strings.xml", stringXML, LocalizationManager.GetAppName(langCodes[0]) );
|
||||
|
||||
|
||||
var list = new List<string>();
|
||||
list.Add( pathToBuiltProject + "/res/values" );
|
||||
foreach (var code in langCodes)
|
||||
{
|
||||
// Android doesn't use zh-CN or zh-TW, instead it uses: zh-rCN, zh-rTW, zh
|
||||
string fixedCode = code;
|
||||
if (fixedCode.StartsWith("zh", System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
string googleCode = GoogleLanguages.GetGoogleLanguageCode(fixedCode);
|
||||
if (googleCode==null) googleCode = fixedCode;
|
||||
fixedCode = (googleCode == "zh-CN") ? "zh-CN" : googleCode;
|
||||
}
|
||||
fixedCode = fixedCode.Replace("-", "-r");
|
||||
|
||||
string dir = pathToBuiltProject + "/res/values-" + fixedCode;
|
||||
|
||||
SetStringsFile( dir, "strings.xml", stringXML, LocalizationManager.GetAppName(code) );
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateFileIfNeeded ( string folder, string fileName, string text )
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!System.IO.Directory.Exists( folder ))
|
||||
System.IO.Directory.CreateDirectory( folder );
|
||||
|
||||
if (!System.IO.File.Exists( folder + "/"+fileName ))
|
||||
System.IO.File.WriteAllText( folder + "/"+fileName, text );
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.Log( e );
|
||||
}
|
||||
}
|
||||
|
||||
static void SetStringsFile(string folder, string fileName, string stringXML, string appName)
|
||||
{
|
||||
try
|
||||
{
|
||||
appName = appName.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace("\"", "\\\"").Replace("'", "\\'");
|
||||
appName = appName.Replace("\r\n", string.Empty).Replace("\n", string.Empty).Replace("\r", string.Empty);
|
||||
|
||||
if (!System.IO.Directory.Exists(folder))
|
||||
System.IO.Directory.CreateDirectory(folder);
|
||||
|
||||
if (!System.IO.File.Exists(folder + "/" + fileName))
|
||||
{
|
||||
// create the string file if it doesn't exist
|
||||
stringXML = string.Format(stringXML, appName);
|
||||
}
|
||||
else
|
||||
{
|
||||
stringXML = System.IO.File.ReadAllText(folder + "/" + fileName);
|
||||
// find app_name
|
||||
var pattern = "\"app_name\">(.*)<\\/string>";
|
||||
var regexPattern = new System.Text.RegularExpressions.Regex(pattern);
|
||||
if (regexPattern.IsMatch(stringXML))
|
||||
{
|
||||
// Override the AppName if it was found
|
||||
stringXML = regexPattern.Replace(stringXML, string.Format("\"app_name\">{0}</string>", appName));
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert the appName if it wasn't there
|
||||
int idx = stringXML.IndexOf("<resources>");
|
||||
if (idx > 0)
|
||||
stringXML = stringXML.Insert(idx + "</resources>".Length, string.Format("\n <string name=\"app_name\">{0}</string>\n", appName));
|
||||
}
|
||||
}
|
||||
System.IO.File.WriteAllText(folder + "/" + fileName, stringXML);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.Log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c8d936531867014da228239d095833c
|
||||
timeCreated: 1489354551
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,102 @@
|
||||
#if UNITY_IOS || UNITY_IPHONE
|
||||
using UnityEditor.Callbacks;
|
||||
using System.Collections;
|
||||
using UnityEditor.iOS_I2Loc.Xcode;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public class PostProcessBuild_IOS
|
||||
{
|
||||
[PostProcessBuild(10000)]
|
||||
public static void ChangeXcodePlist(BuildTarget buildTarget, string pathToBuiltProject)
|
||||
{
|
||||
if (buildTarget != BuildTarget.iOS)
|
||||
return;
|
||||
|
||||
if (LocalizationManager.Sources.Count <= 0)
|
||||
LocalizationManager.UpdateSources();
|
||||
var langCodes = LocalizationManager.GetAllLanguagesCode(false).Concat(LocalizationManager.GetAllLanguagesCode(true)).Distinct().ToList();
|
||||
if (langCodes.Count <= 0)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
//----[ Export localized languages to the info.plist ]---------
|
||||
|
||||
string plistPath = pathToBuiltProject + "/Info.plist";
|
||||
PlistDocument plist = new PlistDocument();
|
||||
plist.ReadFromString(File.ReadAllText(plistPath));
|
||||
|
||||
PlistElementDict rootDict = plist.root;
|
||||
|
||||
// Get Language root
|
||||
var langArray = rootDict.CreateArray("CFBundleLocalizations");
|
||||
|
||||
// Set the Language Codes
|
||||
foreach (var code in langCodes)
|
||||
{
|
||||
if (code == null || code.Length < 2)
|
||||
continue;
|
||||
langArray.AddString(code);
|
||||
}
|
||||
|
||||
rootDict.SetString("CFBundleDevelopmentRegion", langCodes[0]);
|
||||
|
||||
// Write to file
|
||||
File.WriteAllText(plistPath, plist.WriteToString());
|
||||
|
||||
//--[ Localize App Name ]----------
|
||||
|
||||
string LocalizationRoot = pathToBuiltProject + "/I2Localization";
|
||||
if (!Directory.Exists(LocalizationRoot))
|
||||
Directory.CreateDirectory(LocalizationRoot);
|
||||
|
||||
var project = new PBXProject();
|
||||
string projPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
|
||||
//if (!projPath.EndsWith("xcodeproj"))
|
||||
//projPath = projPath.Substring(0, projPath.LastIndexOfAny("/\\".ToCharArray()));
|
||||
|
||||
project.ReadFromFile(projPath);
|
||||
//var targetName = PBXProject.GetUnityTargetName();
|
||||
//string projBuild = project.TargetGuidByName( targetName );
|
||||
|
||||
project.RemoveLocalizationVariantGroup("I2 Localization");
|
||||
// Set the Language Overrides
|
||||
foreach (var code in langCodes)
|
||||
{
|
||||
if (code == null || code.Length < 2)
|
||||
continue;
|
||||
|
||||
var LanguageDirRoot = LocalizationRoot + "/" + code + ".lproj";
|
||||
if (!Directory.Exists(LanguageDirRoot))
|
||||
Directory.CreateDirectory(LanguageDirRoot);
|
||||
|
||||
var infoPlistPath = LanguageDirRoot + "/InfoPlist.strings";
|
||||
var InfoPlist = string.Format("CFBundleDisplayName = \"{0}\";", LocalizationManager.GetAppName(code));
|
||||
File.WriteAllText(infoPlistPath, InfoPlist);
|
||||
|
||||
var langProjectRoot = "I2Localization/"+code+".lproj";
|
||||
|
||||
var stringPaths = LanguageDirRoot + "/Localizable.strings";
|
||||
File.WriteAllText(stringPaths, string.Empty);
|
||||
|
||||
project.AddLocalization(langProjectRoot + "/Localizable.strings", langProjectRoot + "/Localizable.strings", "I2 Localization");
|
||||
project.AddLocalization(langProjectRoot + "/InfoPlist.strings", langProjectRoot + "/InfoPlist.strings", "I2 Localization");
|
||||
}
|
||||
|
||||
project.WriteToFile(projPath);
|
||||
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.Log (e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bf71e767aaa5a245b9d74f326a39549
|
||||
timeCreated: 1489354551
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,30 @@
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public class PostProcessBuild_UnloadLanguages
|
||||
{
|
||||
// [PostProcessBuild]
|
||||
// public static void SaveGlobalSources(BuildTarget buildTarget, string pathToBuiltProject)
|
||||
// {
|
||||
//if (LocalizationManager.Sources.Count <= 0)
|
||||
// LocalizationManager.UpdateSources();
|
||||
|
||||
// foreach (var source in LocalizationManager.Sources.Where(x=>x.IsGlobalSource()))
|
||||
// {
|
||||
// source.SaveLanguages(true, PersistentStorage.eFileType.Streaming);
|
||||
// }
|
||||
// }
|
||||
|
||||
// [PostProcessScene]
|
||||
// public static void SaveLocalSources()
|
||||
// {
|
||||
// if (EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
// return;
|
||||
|
||||
// LanguageSource[] sceneSources = (LanguageSource[])Resources.FindObjectsOfTypeAll(typeof(LanguageSource));
|
||||
// foreach (var source in sceneSources.Where(x=>!x.IsGlobalSource()))
|
||||
// {
|
||||
// source.SaveLanguages(true, PersistentStorage.eFileType.Streaming);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68151af3db9fb734fb3823c020c9b8c0
|
||||
timeCreated: 1489354551
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9276efd8270b104ea614946e5787aa1
|
||||
folderAsset: yes
|
||||
timeCreated: 1489466610
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@@ -0,0 +1,24 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6bcca352fcef3034fb01650308bf47c2
|
||||
timeCreated: 1496388333
|
||||
licenseType: Store
|
||||
PluginImporter:
|
||||
serializedVersion: 1
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
platformData:
|
||||
Any:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
Editor:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
WindowsStoreApps:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,9 @@
|
||||
This is a copy of the Xcode Manipulation API
|
||||
https://bitbucket.org/Unity-Technologies/xcodeapi/overview
|
||||
|
||||
This is already packed inside Unity under the UnityEditor.IOS.XCode namespace,
|
||||
but I'm including here as well because the version that comes with unity doesn't handle
|
||||
localized files.
|
||||
This copy includes the pullrequest #13 (https://bitbucket.org/Unity-Technologies/xcodeapi/pull-requests/13/creation-of-variantgroup-and/diff)
|
||||
|
||||
Hopefully that will be integrated in Unity soon, but until then, I will be including this files here!
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f2eff1a75746804db6c0240420ebed9
|
||||
timeCreated: 1489466907
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,334 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public class UpgradeManager
|
||||
{
|
||||
static bool mAlreadyCheckedPlugins;
|
||||
|
||||
static UpgradeManager()
|
||||
{
|
||||
EditorApplication.update += AutoCheckPlugins;
|
||||
}
|
||||
|
||||
public static void AutoCheckPlugins()
|
||||
{
|
||||
CheckPlugins ();
|
||||
}
|
||||
|
||||
public static void CheckPlugins( bool bForce = false )
|
||||
{
|
||||
EditorApplication.update -= AutoCheckPlugins;
|
||||
|
||||
if (mAlreadyCheckedPlugins && !bForce)
|
||||
return;
|
||||
mAlreadyCheckedPlugins = true;
|
||||
|
||||
EnablePlugins(bForce);
|
||||
CreateLanguageSources();
|
||||
//CreateScriptLocalization();
|
||||
}
|
||||
|
||||
const string EditorPrefs_AutoEnablePlugins = "I2Loc AutoEnablePlugins";
|
||||
|
||||
[MenuItem( "Tools/I2 Localization/Enable Plugins/Force Detection", false, 0 )]
|
||||
public static void ForceCheckPlugins()
|
||||
{
|
||||
CheckPlugins( true );
|
||||
}
|
||||
|
||||
[MenuItem( "Tools/I2 Localization/Enable Plugins/Enable Auto Detection", false, 1 )]
|
||||
public static void EnableAutoCheckPlugins()
|
||||
{
|
||||
EditorPrefs.SetBool(EditorPrefs_AutoEnablePlugins, true);
|
||||
}
|
||||
[MenuItem( "Tools/I2 Localization/Enable Plugins/Enable Auto Detection", true)]
|
||||
public static bool ValidEnableAutoCheckPlugins()
|
||||
{
|
||||
return !EditorPrefs.GetBool(EditorPrefs_AutoEnablePlugins, true);
|
||||
}
|
||||
|
||||
|
||||
[MenuItem( "Tools/I2 Localization/Enable Plugins/Disable Auto Detection", false, 2 )]
|
||||
public static void DisableAutoCheckPlugins()
|
||||
{
|
||||
EditorPrefs.SetBool(EditorPrefs_AutoEnablePlugins, false);
|
||||
}
|
||||
[MenuItem( "Tools/I2 Localization/Enable Plugins/Disable Auto Detection", true)]
|
||||
public static bool ValidDisableAutoCheckPlugins()
|
||||
{
|
||||
return EditorPrefs.GetBool(EditorPrefs_AutoEnablePlugins, true);
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Tools/I2 Localization/Toggle Highlight Localized", false, 17)]
|
||||
public static void ToogleH()
|
||||
{
|
||||
LocalizationManager.HighlightLocalizedTargets = !LocalizationManager.HighlightLocalizedTargets;
|
||||
LocalizationManager.LocalizeAll(true);
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Tools/I2 Localization/Create Temp")]
|
||||
public static void CreateTemp()
|
||||
{
|
||||
LanguageSourceData source = LocalizationManager.Sources[0];
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
source.AddTerm("Term " + i, eTermType.Text, false);
|
||||
source.UpdateDictionary(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void EnablePlugins( bool bForce = false )
|
||||
{
|
||||
if (!bForce)
|
||||
{
|
||||
bool AutoEnablePlugins = EditorPrefs.GetBool(EditorPrefs_AutoEnablePlugins, true);
|
||||
if (!AutoEnablePlugins)
|
||||
return;
|
||||
}
|
||||
//var tar = System.Enum.GetValues(typeof(BuildTargetGroup));
|
||||
foreach (BuildTargetGroup target in Enum.GetValues(typeof(BuildTargetGroup)))
|
||||
if (target!=BuildTargetGroup.Unknown && !target.HasAttributeOfType<ObsoleteAttribute>())
|
||||
{
|
||||
#if UNITY_5_6
|
||||
if (target == BuildTargetGroup.Switch) continue; // some releases of 5.6 defined BuildTargetGroup.Switch but didn't handled it correctly
|
||||
#endif
|
||||
EnablePluginsOnPlatform( target );
|
||||
}
|
||||
|
||||
// Force these one (iPhone has the same # than iOS and iPhone is deprecated, so iOS was been skipped)
|
||||
EnablePluginsOnPlatform(BuildTargetGroup.iOS);
|
||||
}
|
||||
|
||||
static void EnablePluginsOnPlatform( BuildTargetGroup Platform )
|
||||
{
|
||||
string Settings = PlayerSettings.GetScriptingDefineSymbolsForGroup(Platform );
|
||||
|
||||
bool HasChanged = false;
|
||||
List<string> symbols = new List<string>( Settings.Split(';'));
|
||||
|
||||
HasChanged |= UpdateSettings("NGUI", "NGUIDebug", "", ref symbols);
|
||||
HasChanged |= UpdateSettings("DFGUI", "dfPanel", "", ref symbols);
|
||||
HasChanged |= UpdateSettings("TK2D", "tk2dTextMesh", "", ref symbols);
|
||||
HasChanged |= UpdateSettings( "TextMeshPro", "TMPro.TMP_FontAsset", "TextMeshPro", ref symbols );
|
||||
HasChanged |= UpdateSettings( "SVG", "SVGImporter.SVGAsset", "", ref symbols );
|
||||
|
||||
if (HasChanged)
|
||||
{
|
||||
try
|
||||
{
|
||||
Settings = string.Empty;
|
||||
for (int i=0,imax=symbols.Count; i<imax; ++i)
|
||||
{
|
||||
if (i>0) Settings += ";";
|
||||
Settings += symbols[i];
|
||||
}
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(Platform, Settings );
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool UpdateSettings( string mPlugin, string mType, string AssemblyType, ref List<string> symbols)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool hasPluginClass = false;
|
||||
|
||||
if (!string.IsNullOrEmpty( AssemblyType ))
|
||||
{
|
||||
var rtype = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.Where( assembly => assembly.FullName.Contains(AssemblyType) )
|
||||
.Select( assembly => assembly.GetType( mType, false ) )
|
||||
.Where( t => t!=null )
|
||||
.FirstOrDefault();
|
||||
if (rtype != null)
|
||||
hasPluginClass = true;
|
||||
}
|
||||
|
||||
if (!hasPluginClass)
|
||||
hasPluginClass = typeof( Localize ).Assembly.GetType( mType, false )!=null;
|
||||
|
||||
|
||||
bool hasPluginDef = symbols.IndexOf(mPlugin)>=0;
|
||||
|
||||
if (hasPluginClass != hasPluginDef)
|
||||
{
|
||||
if (hasPluginClass) symbols.Add(mPlugin);
|
||||
else symbols.Remove(mPlugin);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
//[MenuItem( "Tools/I2 Localization/Create I2Languages", false, 1)]
|
||||
public static LanguageSourceAsset CreateLanguageSources()
|
||||
{
|
||||
var globalSourcesAsset = AssetDatabase.LoadAssetAtPath<LanguageSourceAsset>(I2GlobalSourcesEditorPath);
|
||||
if (globalSourcesAsset != null)
|
||||
{
|
||||
return globalSourcesAsset;
|
||||
}
|
||||
|
||||
var asset = ScriptableObject.CreateInstance<LanguageSourceAsset>();
|
||||
|
||||
var assetFolder = Application.dataPath + I2GlobalSourcesEditorFolderPath.Replace("Assets", "");
|
||||
if (!Directory.Exists(assetFolder))
|
||||
Directory.CreateDirectory(assetFolder);
|
||||
|
||||
AssetDatabase.CreateAsset(asset, I2GlobalSourcesEditorPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
return asset;
|
||||
|
||||
#if false
|
||||
if (LocalizationManager.GlobalSources==null || LocalizationManager.GlobalSources.Length==0)
|
||||
return;
|
||||
|
||||
Object GlobalSource = Resources.Load(LocalizationManager.GlobalSources[0]);
|
||||
LanguageSourceData sourceData = null;
|
||||
string sourcePath = null;
|
||||
|
||||
if (GlobalSource != null)
|
||||
{
|
||||
if (GlobalSource is GameObject)
|
||||
{
|
||||
// I2Languages was a prefab before 2018.3, it should be converted to an ScriptableObject
|
||||
sourcePath = AssetDatabase.GetAssetPath(GlobalSource);
|
||||
LanguageSource langSourceObj = (GlobalSource as GameObject).GetComponent<LanguageSource>();
|
||||
sourceData = langSourceObj.mSource;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LanguageSourceAsset asset = ScriptableObject.CreateInstance<LanguageSourceAsset>();
|
||||
if (sourceData != null)
|
||||
{
|
||||
asset.mSource = sourceData;
|
||||
AssetDatabase.DeleteAsset(sourcePath);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(sourcePath))
|
||||
{
|
||||
//string PluginPath = GetI2LocalizationPath();
|
||||
string ResourcesFolder = "Assets/Resources";//PluginPath.Substring(0, PluginPath.Length-"/Localization".Length) + "/Resources";
|
||||
|
||||
string fullresFolder = Application.dataPath + ResourcesFolder.Replace("Assets", "");
|
||||
if (!Directory.Exists(fullresFolder))
|
||||
Directory.CreateDirectory(fullresFolder);
|
||||
|
||||
sourcePath = ResourcesFolder + "/" + LocalizationManager.GlobalSources[0] + ".asset";
|
||||
}
|
||||
else
|
||||
{
|
||||
sourcePath = sourcePath.Replace(".prefab", ".asset");
|
||||
}
|
||||
|
||||
AssetDatabase.CreateAsset(asset, sourcePath);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
#endif
|
||||
}
|
||||
|
||||
[MenuItem("Tools/I2 Localization/Help", false, 30)]
|
||||
[MenuItem("Help/I2 Localization")]
|
||||
public static void MainHelp()
|
||||
{
|
||||
Application.OpenURL(LocalizeInspector.HelpURL_Documentation);
|
||||
}
|
||||
|
||||
private const string I2GlobalSourcesEditorFolderPath = "Assets/Editor/I2Localization";
|
||||
private const string I2GlobalSourcesEditorPath = "Assets/Editor/I2Localization/I2Languages.asset";
|
||||
|
||||
[MenuItem("Tools/I2 Localization/Open I2Languages.asset", false, 0)]
|
||||
public static void OpenGlobalSource()
|
||||
{
|
||||
var globalSourcesAsset = CreateLanguageSources();
|
||||
|
||||
if (globalSourcesAsset == null)
|
||||
Debug.LogError($"没有找到数据源 {I2GlobalSourcesEditorPath}");
|
||||
|
||||
Selection.activeObject = globalSourcesAsset;
|
||||
#if false
|
||||
CreateLanguageSources();
|
||||
LanguageSourceAsset GO = Resources.Load<LanguageSourceAsset>(LocalizationManager.GlobalSources[0]);
|
||||
if (GO == null)
|
||||
Debug.Log("Unable to find Global Language at Assets/Resources/" + LocalizationManager.GlobalSources[0] + ".asset");
|
||||
|
||||
Selection.activeObject = GO;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*static void CreateScriptLocalization()
|
||||
{
|
||||
string[] assets = AssetDatabase.FindAssets("ScriptLocalization");
|
||||
if (assets.Length>0)
|
||||
return;
|
||||
|
||||
string ScriptsFolder = "Assets";
|
||||
string ScriptText = LocalizationEditor.mScriptLocalizationHeader + " }\n}";
|
||||
|
||||
System.IO.File.WriteAllText(ScriptsFolder + "/ScriptLocalization.cs", ScriptText);
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}*/
|
||||
|
||||
public static string GetI2LocalizationPath()
|
||||
{
|
||||
string[] assets = AssetDatabase.FindAssets("LocalizationManager");
|
||||
if (assets.Length==0)
|
||||
return string.Empty;
|
||||
|
||||
string PluginPath = AssetDatabase.GUIDToAssetPath(assets[0]);
|
||||
PluginPath = PluginPath.Substring(0, PluginPath.Length - "/Scripts/LocalizationManager.cs".Length);
|
||||
|
||||
return PluginPath;
|
||||
}
|
||||
|
||||
public static string GetI2Path()
|
||||
{
|
||||
string pluginPath = GetI2LocalizationPath();
|
||||
return pluginPath.Substring(0, pluginPath.Length-"/Localization".Length);
|
||||
}
|
||||
|
||||
public static string GetI2CommonResourcesPath()
|
||||
{
|
||||
string I2Path = GetI2Path();
|
||||
return I2Path + "/Resources";
|
||||
}
|
||||
}
|
||||
|
||||
public static class UpgradeManagerHelper
|
||||
{
|
||||
public static bool HasAttributeOfType<T>(this Enum enumVal) where T:Attribute
|
||||
{
|
||||
var type = enumVal.GetType();
|
||||
var memInfo = type.GetMember(enumVal.ToString());
|
||||
var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
|
||||
return attributes.Length > 0;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e61480936111c54883dc051751e0a5f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -6,7 +6,8 @@
|
||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
||||
"GUID:4d1926c9df5b052469a1c63448b7609a",
|
||||
"GUID:6e76b07590314a543b982daed6af2509",
|
||||
"GUID:2373f786d14518f44b0f475db77ba4de"
|
||||
"GUID:2373f786d14518f44b0f475db77ba4de",
|
||||
"GUID:6055be8ebefd69e48b49212b09b47b2f"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
|
3
UnityProject/Assets/TEngine/Runtime/Core/Constant.meta
Normal file
3
UnityProject/Assets/TEngine/Runtime/Core/Constant.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54432698b4aa401c887a0e67d6d00cec
|
||||
timeCreated: 1741755897
|
@@ -0,0 +1,21 @@
|
||||
namespace TEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// 常用设置相关常量。
|
||||
/// </summary>
|
||||
public static partial class Constant
|
||||
{
|
||||
public static class Setting
|
||||
{
|
||||
public const string Language = "Setting.Language";
|
||||
public const string SoundGroupMuted = "Setting.{0}Muted";
|
||||
public const string SoundGroupVolume = "Setting.{0}Volume";
|
||||
public const string MusicMuted = "Setting.MusicMuted";
|
||||
public const string MusicVolume = "Setting.MusicVolume";
|
||||
public const string SoundMuted = "Setting.SoundMuted";
|
||||
public const string SoundVolume = "Setting.SoundVolume";
|
||||
public const string UISoundMuted = "Setting.UISoundMuted";
|
||||
public const string UISoundVolume = "Setting.UISoundVolume";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 277ceef122b84924ae2fb0ac5aae5138
|
||||
timeCreated: 1741755901
|
@@ -265,6 +265,26 @@
|
||||
{
|
||||
return !_enable ? defaultValue : GetString(GetUserKey(key), defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在指定游戏配置项。
|
||||
/// </summary>
|
||||
/// <param name="settingName">要检查游戏配置项的名称。</param>
|
||||
/// <returns>指定的游戏配置项是否存在。</returns>
|
||||
public static bool HasSetting(string settingName)
|
||||
{
|
||||
return PlayerPrefs.HasKey(settingName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存游戏配置。
|
||||
/// </summary>
|
||||
/// <returns>是否保存游戏配置成功。</returns>
|
||||
public static bool Save()
|
||||
{
|
||||
UnityEngine.PlayerPrefs.Save();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c593d66e0920d6a43a58e3cdc76e64f6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f9a3530624fd5c47a2dc16eb641ddb8
|
||||
folderAsset: yes
|
||||
timeCreated: 1520745251
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,286 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public static class PersistentStorage
|
||||
{
|
||||
static I2CustomPersistentStorage mStorage;
|
||||
|
||||
public enum eFileType { Raw, Persistent, Temporal, Streaming }
|
||||
|
||||
#region PlayerPrefs
|
||||
public static void SetSetting_String(string key, string value)
|
||||
{
|
||||
if (mStorage == null) mStorage = new I2CustomPersistentStorage();
|
||||
mStorage.SetSetting_String(key, value);
|
||||
}
|
||||
|
||||
public static string GetSetting_String(string key, string defaultValue)
|
||||
{
|
||||
if (mStorage == null) mStorage = new I2CustomPersistentStorage();
|
||||
return mStorage.GetSetting_String(key, defaultValue);
|
||||
}
|
||||
|
||||
public static void DeleteSetting(string key)
|
||||
{
|
||||
if (mStorage == null) mStorage = new I2CustomPersistentStorage();
|
||||
mStorage.DeleteSetting(key);
|
||||
}
|
||||
|
||||
public static bool HasSetting( string key )
|
||||
{
|
||||
if (mStorage == null) mStorage = new I2CustomPersistentStorage();
|
||||
return mStorage.HasSetting(key);
|
||||
}
|
||||
|
||||
public static void ForceSaveSettings()
|
||||
{
|
||||
if (mStorage == null) mStorage = new I2CustomPersistentStorage();
|
||||
mStorage.ForceSaveSettings();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region File Management
|
||||
|
||||
public static bool CanAccessFiles()
|
||||
{
|
||||
if (mStorage == null) mStorage = new I2CustomPersistentStorage();
|
||||
return mStorage.CanAccessFiles();
|
||||
}
|
||||
|
||||
public static bool SaveFile(eFileType fileType, string fileName, string data, bool logExceptions = true)
|
||||
{
|
||||
if (mStorage == null) mStorage = new I2CustomPersistentStorage();
|
||||
return mStorage.SaveFile(fileType, fileName, data, logExceptions);
|
||||
}
|
||||
|
||||
public static string LoadFile(eFileType fileType, string fileName, bool logExceptions=true)
|
||||
{
|
||||
if (mStorage == null) mStorage = new I2CustomPersistentStorage();
|
||||
return mStorage.LoadFile(fileType, fileName, logExceptions);
|
||||
}
|
||||
|
||||
public static bool DeleteFile(eFileType fileType, string fileName, bool logExceptions = true)
|
||||
{
|
||||
if (mStorage == null) mStorage = new I2CustomPersistentStorage();
|
||||
return mStorage.DeleteFile(fileType, fileName, logExceptions);
|
||||
}
|
||||
|
||||
public static bool HasFile(eFileType fileType, string fileName, bool logExceptions = true)
|
||||
{
|
||||
if (mStorage == null) mStorage = new I2CustomPersistentStorage();
|
||||
return mStorage.HasFile(fileType, fileName, logExceptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public abstract class I2BasePersistentStorage
|
||||
{
|
||||
#region PlayerPrefs
|
||||
public virtual void SetSetting_String(string key, string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Use PlayerPrefs, but if the data is bigger than the limit, split it into multiple entries
|
||||
var len = value.Length;
|
||||
int maxLength = 8000;
|
||||
if (len<=maxLength)
|
||||
{
|
||||
PlayerPrefs.SetString(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
int numSections = Mathf.CeilToInt(len / (float)maxLength);
|
||||
for (int i=0; i<numSections; ++i)
|
||||
{
|
||||
int iStart = maxLength * i;
|
||||
PlayerPrefs.SetString($"[I2split]{i}{key}", value.Substring(iStart, Mathf.Min(maxLength, len-iStart)));
|
||||
}
|
||||
PlayerPrefs.SetString(key, "[$I2#@div$]" + numSections);
|
||||
}
|
||||
}
|
||||
catch (Exception) { Debug.LogError("Error saving PlayerPrefs " + key); }
|
||||
}
|
||||
|
||||
public virtual string GetSetting_String(string key, string defaultValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = PlayerPrefs.GetString(key, defaultValue);
|
||||
|
||||
// Check if the data is splitted, if so, concat all the sections
|
||||
if (!string.IsNullOrEmpty(data) && data.StartsWith("[I2split]", StringComparison.Ordinal))
|
||||
{
|
||||
int nSections = int.Parse(data.Substring("[I2split]".Length), CultureInfo.InvariantCulture);
|
||||
data = "";
|
||||
for (int i=0; i<nSections; ++i)
|
||||
{
|
||||
data += PlayerPrefs.GetString($"[I2split]{i}{key}", "");
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Debug.LogError("Error loading PlayerPrefs " + key);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void DeleteSetting( string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = PlayerPrefs.GetString(key, null);
|
||||
|
||||
// If the data is splitted, delete each section as well
|
||||
if (!string.IsNullOrEmpty(data) && data.StartsWith("[I2split]", StringComparison.Ordinal))
|
||||
{
|
||||
int nSections = int.Parse(data.Substring("[I2split]".Length), CultureInfo.InvariantCulture);
|
||||
for (int i = 0; i < nSections; ++i)
|
||||
{
|
||||
PlayerPrefs.DeleteKey($"[I2split]{i}{key}");
|
||||
}
|
||||
}
|
||||
PlayerPrefs.DeleteKey(key);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Debug.LogError("Error deleting PlayerPrefs " + key);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ForceSaveSettings()
|
||||
{
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
public virtual bool HasSetting(string key)
|
||||
{
|
||||
return PlayerPrefs.HasKey(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Files
|
||||
|
||||
public virtual bool CanAccessFiles()
|
||||
{
|
||||
#if UNITY_SWITCH || UNITY_WSA
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
string UpdateFilename(PersistentStorage.eFileType fileType, string fileName)
|
||||
{
|
||||
switch (fileType)
|
||||
{
|
||||
case PersistentStorage.eFileType.Persistent: fileName = Application.persistentDataPath + "/" + fileName; break;
|
||||
case PersistentStorage.eFileType.Temporal: fileName = Application.temporaryCachePath + "/" + fileName; break;
|
||||
case PersistentStorage.eFileType.Streaming: fileName = Application.streamingAssetsPath + "/" + fileName; break;
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public virtual bool SaveFile(PersistentStorage.eFileType fileType, string fileName, string data, bool logExceptions = true)
|
||||
{
|
||||
if (!CanAccessFiles())
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
fileName = UpdateFilename(fileType, fileName);
|
||||
File.WriteAllText(fileName, data, Encoding.UTF8);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (logExceptions)
|
||||
Debug.LogError("Error saving file '" + fileName + "'\n" + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual string LoadFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true)
|
||||
{
|
||||
if (!CanAccessFiles())
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
fileName = UpdateFilename(fileType, fileName);
|
||||
return File.ReadAllText(fileName, Encoding.UTF8);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (logExceptions)
|
||||
Debug.LogError("Error loading file '" + fileName + "'\n" + e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool DeleteFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true)
|
||||
{
|
||||
if (!CanAccessFiles())
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
fileName = UpdateFilename(fileType, fileName);
|
||||
File.Delete(fileName);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (logExceptions)
|
||||
Debug.LogError("Error deleting file '" + fileName + "'\n" + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool HasFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true)
|
||||
{
|
||||
if (!CanAccessFiles())
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
fileName = UpdateFilename(fileType, fileName);
|
||||
return File.Exists(fileName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (logExceptions) Debug.LogError("Error requesting file '" + fileName + "'\n" + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class I2CustomPersistentStorage : I2BasePersistentStorage
|
||||
{
|
||||
//public override void SetSetting_String(string key, string value)
|
||||
//public override string GetSetting_String(string key, string defaultValue)
|
||||
//public override void DeleteSetting(string key)
|
||||
//public override void ForceSaveSettings()
|
||||
//public override bool HasSetting(string key)
|
||||
|
||||
//public virtual bool CanAccessFiles();
|
||||
//public override bool SaveFile(PersistentStorage.eFileType fileType, string fileName, string data, bool logExceptions = true);
|
||||
//public override string LoadFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true);
|
||||
//public override bool DeleteFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true);
|
||||
//public override bool HasFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true);
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec5b9e0d683ff2b409340ac814051bb8
|
||||
timeCreated: 1507704861
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,204 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using UnityEngine.InputSystem;
|
||||
#endif
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public class BaseSpecializationManager
|
||||
{
|
||||
public string[] mSpecializations;
|
||||
public Dictionary<string, string> mSpecializationsFallbacks;
|
||||
|
||||
public virtual void InitializeSpecializations()
|
||||
{
|
||||
mSpecializations = new[] { "Any", "PC", "Touch", "Controller", "VR",
|
||||
"XBox", "PS4", "PS5", "OculusVR", "ViveVR", "GearVR", "Android", "IOS",
|
||||
"Switch"
|
||||
};
|
||||
mSpecializationsFallbacks = new Dictionary<string, string>(System.StringComparer.Ordinal)
|
||||
{
|
||||
{ "XBox", "Controller" }, { "PS4", "Controller" },
|
||||
{ "OculusVR", "VR" }, { "ViveVR", "VR" }, { "GearVR", "VR" },
|
||||
{ "Android", "Touch" }, { "IOS", "Touch" }
|
||||
};
|
||||
}
|
||||
|
||||
public virtual string GetCurrentSpecialization()
|
||||
{
|
||||
if (mSpecializations == null)
|
||||
InitializeSpecializations();
|
||||
|
||||
#if UNITY_ANDROID
|
||||
return "Android";
|
||||
#elif UNITY_IOS
|
||||
return "IOS";
|
||||
#elif UNITY_PS4
|
||||
return "PS4";
|
||||
#elif UNITY_XBOXONE
|
||||
return "XBox";
|
||||
#elif UNITY_SWITCH
|
||||
return "Switch";
|
||||
#elif UNITY_STANDALONE || UNITY_WEBGL
|
||||
return "PC";
|
||||
#else
|
||||
return (IsTouchInputSupported() ? "Touch" : "PC");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsTouchInputSupported()
|
||||
{
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
return Touchscreen.current != null;
|
||||
#else
|
||||
return UnityEngine.Input.touchSupported;
|
||||
#endif
|
||||
}
|
||||
|
||||
public virtual string GetFallbackSpecialization(string specialization)
|
||||
{
|
||||
if (mSpecializationsFallbacks == null)
|
||||
InitializeSpecializations();
|
||||
|
||||
string fallback;
|
||||
if (mSpecializationsFallbacks.TryGetValue(specialization, out fallback))
|
||||
return fallback;
|
||||
return "Any";
|
||||
}
|
||||
}
|
||||
public class SpecializationManager : BaseSpecializationManager
|
||||
{
|
||||
public static SpecializationManager Singleton = new SpecializationManager();
|
||||
|
||||
private SpecializationManager()
|
||||
{
|
||||
InitializeSpecializations();
|
||||
}
|
||||
|
||||
public static string GetSpecializedText(string text, string specialization = null)
|
||||
{
|
||||
var idxFirst = text.IndexOf("[i2s_", StringComparison.Ordinal);
|
||||
if (idxFirst < 0)
|
||||
return text;
|
||||
|
||||
if (string.IsNullOrEmpty(specialization))
|
||||
specialization = Singleton.GetCurrentSpecialization();
|
||||
|
||||
while (!string.IsNullOrEmpty(specialization) && specialization != "Any")
|
||||
{
|
||||
var tag = "[i2s_" + specialization + "]";
|
||||
int idx = text.IndexOf(tag, StringComparison.Ordinal);
|
||||
if (idx < 0)
|
||||
{
|
||||
specialization = Singleton.GetFallbackSpecialization(specialization);
|
||||
continue;
|
||||
}
|
||||
|
||||
idx += tag.Length;
|
||||
var idxEnd = text.IndexOf("[i2s_", idx, StringComparison.Ordinal);
|
||||
if (idxEnd < 0) idxEnd = text.Length;
|
||||
|
||||
return text.Substring(idx, idxEnd - idx);
|
||||
}
|
||||
|
||||
return text.Substring(0, idxFirst);
|
||||
}
|
||||
|
||||
public static string SetSpecializedText(string text, string newText, string specialization)
|
||||
{
|
||||
if (string.IsNullOrEmpty(specialization))
|
||||
specialization = "Any";
|
||||
if ((text==null || !text.Contains("[i2s_")) && specialization=="Any")
|
||||
{
|
||||
return newText;
|
||||
}
|
||||
|
||||
var dict = GetSpecializations(text);
|
||||
dict[specialization] = newText;
|
||||
|
||||
return SetSpecializedText(dict);
|
||||
}
|
||||
|
||||
public static string SetSpecializedText( Dictionary<string,string> specializations )
|
||||
{
|
||||
string text;
|
||||
if (!specializations.TryGetValue("Any", out text))
|
||||
text = string.Empty;
|
||||
|
||||
foreach (var kvp in specializations)
|
||||
{
|
||||
if (kvp.Key != "Any" && !string.IsNullOrEmpty(kvp.Value))
|
||||
text += "[i2s_" + kvp.Key + "]" + kvp.Value;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static Dictionary<string, string> GetSpecializations(string text, Dictionary<string, string> buffer = null)
|
||||
{
|
||||
if (buffer == null)
|
||||
buffer = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
else
|
||||
buffer.Clear();
|
||||
|
||||
if (text==null)
|
||||
{
|
||||
buffer["Any"] = "";
|
||||
return buffer;
|
||||
}
|
||||
|
||||
var idxFirst = 0;
|
||||
var idxEnd = text.IndexOf("[i2s_", StringComparison.Ordinal);
|
||||
if (idxEnd < 0)
|
||||
idxEnd=text.Length;
|
||||
|
||||
buffer["Any"] = text.Substring(0, idxEnd);
|
||||
idxFirst = idxEnd;
|
||||
|
||||
while (idxFirst<text.Length)
|
||||
{
|
||||
idxFirst += "[i2s_".Length;
|
||||
int idx = text.IndexOf(']', idxFirst);
|
||||
if (idx < 0) break;
|
||||
var tag = text.Substring(idxFirst, idx - idxFirst);
|
||||
idxFirst = idx+1; // ']'
|
||||
|
||||
idxEnd = text.IndexOf("[i2s_", idxFirst, StringComparison.Ordinal);
|
||||
if (idxEnd < 0) idxEnd = text.Length;
|
||||
var value = text.Substring(idxFirst, idxEnd - idxFirst);
|
||||
|
||||
buffer[tag] = value;
|
||||
idxFirst = idxEnd;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
public static void AppendSpecializations(string text, List<string> list=null)
|
||||
{
|
||||
if (text == null)
|
||||
return;
|
||||
|
||||
if (list == null)
|
||||
list = new List<string>();
|
||||
|
||||
if (!list.Contains("Any"))
|
||||
list.Add("Any");
|
||||
|
||||
var idxFirst = 0;
|
||||
while (idxFirst<text.Length)
|
||||
{
|
||||
idxFirst = text.IndexOf("[i2s_", idxFirst, StringComparison.Ordinal);
|
||||
if (idxFirst < 0)
|
||||
break;
|
||||
|
||||
idxFirst += "[i2s_".Length;
|
||||
int idx = text.IndexOf(']', idxFirst);
|
||||
if (idx < 0)
|
||||
break;
|
||||
|
||||
var tag = text.Substring(idxFirst, idx - idxFirst);
|
||||
if (!list.Contains(tag))
|
||||
list.Add(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a72e5d6dba43bf249987cd37521e38bb
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
[Serializable]
|
||||
public class EventCallback
|
||||
{
|
||||
public MonoBehaviour Target;
|
||||
public string MethodName = string.Empty;
|
||||
|
||||
public void Execute( Object Sender = null )
|
||||
{
|
||||
if (HasCallback() && Application.isPlaying)
|
||||
Target.gameObject.SendMessage(MethodName, Sender, SendMessageOptions.DontRequireReceiver);
|
||||
}
|
||||
|
||||
public bool HasCallback()
|
||||
{
|
||||
return Target != null && !string.IsNullOrEmpty (MethodName);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79fbe85a671c1254880b1fc083a723e5
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0562689eb1644e4913111b4facfb9e5
|
||||
timeCreated: 1709181364
|
@@ -0,0 +1,132 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public class RealTimeTranslation : MonoBehaviour
|
||||
{
|
||||
string OriginalText = "This is an example showing how to use the google translator to translate chat messages within the game.\nIt also supports multiline translations.",
|
||||
TranslatedText = string.Empty;
|
||||
bool IsTranslating;
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
GUILayout.Label("Translate:");
|
||||
OriginalText = GUILayout.TextArea(OriginalText, GUILayout.Width(Screen.width));
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("English -> Español", GUILayout.Height(100))) StartTranslating("en", "es");
|
||||
if (GUILayout.Button("Español -> English", GUILayout.Height(100))) StartTranslating("es", "en");
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.TextArea("Multiple Translation with 1 call:\n'This is an example' -> en,zh\n'Hola' -> en");
|
||||
if (GUILayout.Button("Multi Translate", GUILayout.ExpandHeight(true))) ExampleMultiTranslations_Async();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
||||
GUILayout.TextArea(TranslatedText, GUILayout.Width(Screen.width));
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
|
||||
if (IsTranslating)
|
||||
{
|
||||
GUILayout.Label("Contacting Google....");
|
||||
}
|
||||
}
|
||||
|
||||
public void StartTranslating(string fromCode, string toCode)
|
||||
{
|
||||
IsTranslating = true;
|
||||
|
||||
// fromCode could be "auto" to autodetect the language
|
||||
GoogleTranslation.Translate(OriginalText, fromCode, toCode, OnTranslationReady);
|
||||
|
||||
// can also use the ForceTranslate version: (it will block the main thread until the translation is returned)
|
||||
//var translation = GoogleTranslation.ForceTranslate(OriginalText, fromCode, toCode);
|
||||
//Debug.Log(translation);
|
||||
}
|
||||
|
||||
void OnTranslationReady(string Translation, string errorMsg)
|
||||
{
|
||||
IsTranslating = false;
|
||||
|
||||
if (errorMsg != null)
|
||||
Debug.LogError(errorMsg);
|
||||
else
|
||||
TranslatedText = Translation;
|
||||
}
|
||||
|
||||
public void ExampleMultiTranslations_Blocking()
|
||||
{
|
||||
// This shows how to ask for many translations
|
||||
var dict = new Dictionary<string, TranslationQuery>();
|
||||
GoogleTranslation.AddQuery("This is an example", "en", "es", dict);
|
||||
GoogleTranslation.AddQuery("This is an example", "auto", "zh", dict);
|
||||
GoogleTranslation.AddQuery("Hola", "es", "en", dict);
|
||||
|
||||
if (!GoogleTranslation.ForceTranslate(dict))
|
||||
return;
|
||||
|
||||
Debug.Log(GoogleTranslation.GetQueryResult("This is an example", "en", dict));
|
||||
Debug.Log(GoogleTranslation.GetQueryResult("This is an example", "zh", dict));
|
||||
Debug.Log(GoogleTranslation.GetQueryResult("This is an example", "", dict)); // This returns ANY translation of that text (in this case, the first one 'en')
|
||||
Debug.Log(dict["Hola"].Results[0]); // example of getting the translation directly from the Results
|
||||
}
|
||||
|
||||
public void ExampleMultiTranslations_Async()
|
||||
{
|
||||
IsTranslating = true;
|
||||
|
||||
// This shows how to ask for many translations
|
||||
var dict = new Dictionary<string, TranslationQuery>();
|
||||
GoogleTranslation.AddQuery("This is an example", "en", "es", dict);
|
||||
GoogleTranslation.AddQuery("This is an example", "auto", "zh", dict);
|
||||
GoogleTranslation.AddQuery("Hola", "es", "en", dict);
|
||||
|
||||
GoogleTranslation.Translate(dict, OnMultitranslationReady);
|
||||
}
|
||||
|
||||
void OnMultitranslationReady(Dictionary<string, TranslationQuery> dict, string errorMsg)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(errorMsg))
|
||||
{
|
||||
Debug.LogError(errorMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
IsTranslating = false;
|
||||
TranslatedText = "";
|
||||
|
||||
TranslatedText += GoogleTranslation.GetQueryResult("This is an example", "es", dict) + "\n";
|
||||
TranslatedText += GoogleTranslation.GetQueryResult("This is an example", "zh", dict) + "\n";
|
||||
TranslatedText += GoogleTranslation.GetQueryResult("This is an example", "", dict) + "\n"; // This returns ANY translation of that text (in this case, the first one 'en')
|
||||
TranslatedText += dict["Hola"].Results[0]; // example of getting the translation directly from the Results
|
||||
}
|
||||
|
||||
#region This methods are used in the publisher's Unity Tests
|
||||
|
||||
public bool IsWaitingForTranslation()
|
||||
{
|
||||
return IsTranslating;
|
||||
}
|
||||
|
||||
public string GetTranslatedText()
|
||||
{
|
||||
return TranslatedText;
|
||||
}
|
||||
|
||||
public void SetOriginalText( string text )
|
||||
{
|
||||
OriginalText = text;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c09397e14dc19fb4ab38f8216b0759a4
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -450
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dda5008126b59ad4bad4c9d2626a2345
|
||||
folderAsset: yes
|
||||
timeCreated: 1461137613
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,648 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
public enum ePluralType { Zero, One, Two, Few, Many, Plural }
|
||||
|
||||
public static class GoogleLanguages
|
||||
{
|
||||
public static string GetLanguageCode(string Filter, bool ShowWarnings = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Filter))
|
||||
return string.Empty;
|
||||
|
||||
string[] Filters = Filter.ToLowerInvariant().Split(" /(),".ToCharArray());
|
||||
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (LanguageMatchesFilter(kvp.Key, Filters))
|
||||
return kvp.Value.Code;
|
||||
|
||||
if (ShowWarnings)
|
||||
Debug.Log($"Language '{Filter}' not recognized. Please, add the language code to GoogleTranslation.cs");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public static List<string> GetLanguagesForDropdown(string Filter, string CodesToExclude)
|
||||
{
|
||||
string[] Filters = Filter.ToLowerInvariant().Split(" /(),".ToCharArray());
|
||||
|
||||
List<string> Languages = new List<string>();
|
||||
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (string.IsNullOrEmpty(Filter) || LanguageMatchesFilter(kvp.Key, Filters))
|
||||
{
|
||||
string code = string.Concat("[" + kvp.Value.Code + "]");
|
||||
if (!CodesToExclude.Contains(code))
|
||||
Languages.Add(kvp.Key + " " + code);
|
||||
}
|
||||
|
||||
// Add headers to variants (e.g. "English/English" before all English variants
|
||||
for (int i = Languages.Count - 2; i >= 0; --i)
|
||||
{
|
||||
string Prefix = Languages[i].Substring(0, Languages[i].IndexOf(" ["));
|
||||
if (Languages[i + 1].StartsWith(Prefix, StringComparison.Ordinal))
|
||||
{
|
||||
Languages[i] = Prefix + "/" + Languages[i];
|
||||
Languages.Insert(i + 1, Prefix + "/");
|
||||
}
|
||||
}
|
||||
return Languages;
|
||||
}
|
||||
|
||||
// "Engl Unit" matches "English/United States"
|
||||
static bool LanguageMatchesFilter(string Language, string[] Filters)
|
||||
{
|
||||
Language = Language.ToLowerInvariant();
|
||||
for (int i = 0, imax = Filters.Length; i < imax; ++i)
|
||||
if (Filters[i] != "")
|
||||
{
|
||||
if (!Language.Contains(Filters[i].ToLower()))
|
||||
return false;
|
||||
Language = Language.Remove(Language.IndexOf(Filters[i], StringComparison.Ordinal), Filters[i].Length);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// "Arabic/Algeria [ar-XX]" returns "Arabic (Algeria)"
|
||||
// "English/English [en]" returns "English"
|
||||
public static string GetFormatedLanguageName(string Language)
|
||||
{
|
||||
string BaseLanguage = string.Empty;
|
||||
|
||||
//-- Remove code --------
|
||||
int Index = Language.IndexOf(" [", StringComparison.Ordinal);
|
||||
if (Index > 0)
|
||||
Language = Language.Substring(0, Index);
|
||||
|
||||
//-- Check for main language: "English/English [en]" returns "English" -----------
|
||||
Index = Language.IndexOf('/');
|
||||
if (Index > 0)
|
||||
{
|
||||
BaseLanguage = Language.Substring(0, Index);
|
||||
if (Language == BaseLanguage + "/" + BaseLanguage)
|
||||
return BaseLanguage;
|
||||
|
||||
//-- Convert variants into right format
|
||||
Language = Language.Replace("/", " (") + ")";
|
||||
}
|
||||
|
||||
return Language;
|
||||
}
|
||||
|
||||
// English British -> "English Canada [en-CA]"
|
||||
public static string GetCodedLanguage(string Language, string code)
|
||||
{
|
||||
string DefaultCode = GetLanguageCode(Language);
|
||||
if (string.Compare(code, DefaultCode, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
return Language;
|
||||
return string.Concat(Language, " [", code, "]");
|
||||
}
|
||||
|
||||
// "English Canada [en-CA]" -> "English Canada", "en-CA"
|
||||
public static void UnPackCodeFromLanguageName(string CodedLanguage, out string Language, out string code)
|
||||
{
|
||||
if (string.IsNullOrEmpty(CodedLanguage))
|
||||
{
|
||||
Language = string.Empty;
|
||||
code = string.Empty;
|
||||
return;
|
||||
}
|
||||
int Index = CodedLanguage.IndexOf("[", StringComparison.Ordinal);
|
||||
if (Index < 0)
|
||||
{
|
||||
Language = CodedLanguage;
|
||||
code = GetLanguageCode(Language);
|
||||
}
|
||||
else
|
||||
{
|
||||
Language = CodedLanguage.Substring(0, Index).Trim();
|
||||
code = CodedLanguage.Substring(Index + 1, CodedLanguage.IndexOf("]", Index, StringComparison.Ordinal) - Index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetGoogleLanguageCode(string InternationalCode)
|
||||
{
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (InternationalCode == kvp.Value.Code)
|
||||
{
|
||||
if (kvp.Value.GoogleCode == "-")
|
||||
return null;
|
||||
return !string.IsNullOrEmpty(kvp.Value.GoogleCode) ? kvp.Value.GoogleCode : InternationalCode;
|
||||
}
|
||||
|
||||
return InternationalCode;
|
||||
}
|
||||
|
||||
public static string GetLanguageName(string code, bool useParenthesesForRegion=false, bool allowDiscardRegion=true)
|
||||
{
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (code == kvp.Value.Code)
|
||||
{
|
||||
var langName = kvp.Key;
|
||||
if (useParenthesesForRegion)
|
||||
{
|
||||
int idx = langName.IndexOf('/');
|
||||
if (idx > 0)
|
||||
langName = langName.Substring(0, idx) + " (" + langName.Substring(idx + 1) + ")";
|
||||
}
|
||||
return langName;
|
||||
}
|
||||
|
||||
if (allowDiscardRegion)
|
||||
{
|
||||
int iCode = code.IndexOf("-", StringComparison.Ordinal);
|
||||
if (iCode > 0)
|
||||
return GetLanguageName(code.Substring(0,iCode), useParenthesesForRegion, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<string> GetAllInternationalCodes()
|
||||
{
|
||||
var set = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
foreach (var kvp in mLanguageDef)
|
||||
set.Add(kvp.Value.Code);
|
||||
|
||||
return new List<string>(set);
|
||||
}
|
||||
|
||||
public static bool LanguageCode_HasJoinedWord(string languageCode)
|
||||
{
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (languageCode == kvp.Value.GoogleCode || languageCode==kvp.Value.Code )
|
||||
return kvp.Value.HasJoinedWords;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public struct LanguageCodeDef
|
||||
{
|
||||
public string Code; // Language International Code
|
||||
public string GoogleCode; // Google Translator doesn't support all languages, this is the code of closest supported language
|
||||
public bool HasJoinedWords; // Some languages (e.g. Chinese, Japanese and Thai) don't add spaces to their words (all characters are placed toguether)
|
||||
public int PluralRule;
|
||||
}
|
||||
|
||||
public static Dictionary<string, LanguageCodeDef> mLanguageDef = new Dictionary<string, LanguageCodeDef>(StringComparer.Ordinal)
|
||||
{
|
||||
/**/{"Abkhazian", new LanguageCodeDef {PluralRule=1, Code="ab", GoogleCode="-"}},
|
||||
/**/{"Afar", new LanguageCodeDef {PluralRule=1, Code="aa", GoogleCode="-"}},
|
||||
{"Afrikaans", new LanguageCodeDef {PluralRule=1, Code="af"}},
|
||||
/**/{"Akan", new LanguageCodeDef {PluralRule=1, Code="ak", GoogleCode="-"}},
|
||||
{"Albanian", new LanguageCodeDef {PluralRule=1, Code="sq"}},
|
||||
/**/{"Amharic", new LanguageCodeDef {PluralRule=1, Code="am"}},
|
||||
{"Arabic", new LanguageCodeDef {PluralRule=11, Code="ar"}},
|
||||
{"Arabic/Algeria", new LanguageCodeDef {PluralRule=11, Code="ar-DZ", GoogleCode="ar"}},
|
||||
{"Arabic/Bahrain", new LanguageCodeDef {PluralRule=11, Code="ar-BH", GoogleCode="ar"}},
|
||||
{"Arabic/Egypt", new LanguageCodeDef {PluralRule=11, Code="ar-EG", GoogleCode="ar"}},
|
||||
{"Arabic/Iraq", new LanguageCodeDef {PluralRule=11, Code="ar-IQ", GoogleCode="ar"}},
|
||||
{"Arabic/Jordan", new LanguageCodeDef {PluralRule=11, Code="ar-JO", GoogleCode="ar"}},
|
||||
{"Arabic/Kuwait", new LanguageCodeDef {PluralRule=11, Code="ar-KW", GoogleCode="ar"}},
|
||||
{"Arabic/Lebanon", new LanguageCodeDef {PluralRule=11, Code="ar-LB", GoogleCode="ar"}},
|
||||
{"Arabic/Libya", new LanguageCodeDef {PluralRule=11, Code="ar-LY", GoogleCode="ar"}},
|
||||
{"Arabic/Morocco", new LanguageCodeDef {PluralRule=11, Code="ar-MA", GoogleCode="ar"}},
|
||||
{"Arabic/Oman", new LanguageCodeDef {PluralRule=11, Code="ar-OM", GoogleCode="ar"}},
|
||||
{"Arabic/Qatar", new LanguageCodeDef {PluralRule=11, Code="ar-QA", GoogleCode="ar"}},
|
||||
{"Arabic/Saudi Arabia", new LanguageCodeDef {PluralRule=11, Code="ar-SA", GoogleCode="ar"}},
|
||||
{"Arabic/Syria", new LanguageCodeDef {PluralRule=11, Code="ar-SY", GoogleCode="ar"}},
|
||||
{"Arabic/Tunisia", new LanguageCodeDef {PluralRule=11, Code="ar-TN", GoogleCode="ar"}},
|
||||
{"Arabic/U.A.E.", new LanguageCodeDef {PluralRule=11, Code="ar-AE", GoogleCode="ar"}},
|
||||
{"Arabic/Yemen", new LanguageCodeDef {PluralRule=11, Code="ar-YE", GoogleCode="ar"}},
|
||||
/**/{"Aragonese", new LanguageCodeDef {PluralRule=1, Code="an", GoogleCode="-"}},
|
||||
{"Armenian", new LanguageCodeDef {PluralRule=1, Code="hy"}},
|
||||
/**/{"Assamese", new LanguageCodeDef {PluralRule=1, Code="as", GoogleCode="-"}},
|
||||
/**/{"Avaric", new LanguageCodeDef {PluralRule=1, Code="av", GoogleCode="-"}},
|
||||
/**/{"Avestan", new LanguageCodeDef {PluralRule=1, Code="ae", GoogleCode="-"}},
|
||||
/**/{"Aymara", new LanguageCodeDef {PluralRule=1, Code="ay", GoogleCode="-"}},
|
||||
{"Azerbaijani", new LanguageCodeDef {PluralRule=1, Code="az"}},
|
||||
/**/{"Bambara", new LanguageCodeDef {PluralRule=1, Code="bm", GoogleCode="-"}},
|
||||
/**/{"Bashkir", new LanguageCodeDef {PluralRule=1, Code="ba", GoogleCode="-"}},
|
||||
{"Basque", new LanguageCodeDef {PluralRule=1, Code="eu"}},
|
||||
{"Basque/Spain", new LanguageCodeDef {PluralRule=1, Code="eu-ES", GoogleCode="eu"}},
|
||||
{"Belarusian", new LanguageCodeDef {PluralRule=6, Code="be"}},
|
||||
/**/{"Bengali", new LanguageCodeDef {PluralRule=1, Code="bn"}},
|
||||
/**/{"Bihari", new LanguageCodeDef {PluralRule=1, Code="bh", GoogleCode="-"}},
|
||||
/**/{"Bislama", new LanguageCodeDef {PluralRule=1, Code="bi", GoogleCode="-"}},
|
||||
{"Bosnian", new LanguageCodeDef {PluralRule=6, Code="bs"}},
|
||||
/**/{"Breton", new LanguageCodeDef {PluralRule=1, Code="br", GoogleCode="-"}},
|
||||
{"Bulgariaa", new LanguageCodeDef {PluralRule=1, Code="bg"}},
|
||||
/**/{"Burmese", new LanguageCodeDef {PluralRule=1, Code="my"}},
|
||||
{"Catalan", new LanguageCodeDef {PluralRule=1, Code="ca"}},
|
||||
/**/{"Chamorro", new LanguageCodeDef {PluralRule=1, Code="ch", GoogleCode="-"}},
|
||||
/**/{"Chechen", new LanguageCodeDef {PluralRule=1, Code="ce", GoogleCode="-"}},
|
||||
/**/{"Chichewa", new LanguageCodeDef {PluralRule=1, Code="ny"}},
|
||||
{"Chinese", new LanguageCodeDef {PluralRule=0, Code="zh", GoogleCode="zh-CN", HasJoinedWords=true}},
|
||||
{"Chinese/Hong Kong", new LanguageCodeDef {PluralRule=0, Code="zh-HK", GoogleCode="zh-TW", HasJoinedWords=true}},
|
||||
{"Chinese/Macau", new LanguageCodeDef {PluralRule=0, Code="zh-MO", GoogleCode="zh-CN", HasJoinedWords=true}},
|
||||
{"Chinese/PRC", new LanguageCodeDef {PluralRule=0, Code="zh-CN", GoogleCode="zh-CN", HasJoinedWords=true}},
|
||||
{"Chinese/Simplified", new LanguageCodeDef {PluralRule=0, Code="zh-CN", GoogleCode="zh-CN", HasJoinedWords=true}},
|
||||
{"Chinese/Singapore", new LanguageCodeDef {PluralRule=0, Code="zh-SG", GoogleCode="zh-CN", HasJoinedWords=true}},
|
||||
{"Chinese/Taiwan", new LanguageCodeDef {PluralRule=0, Code="zh-TW", GoogleCode="zh-TW", HasJoinedWords=true}},
|
||||
{"Chinese/Traditional", new LanguageCodeDef {PluralRule=0, Code="zh-TW", GoogleCode="zh-TW", HasJoinedWords=true}},
|
||||
/**/{"Chuvash", new LanguageCodeDef {PluralRule=1, Code="cv", GoogleCode="-"}},
|
||||
/**/{"Cornish", new LanguageCodeDef {PluralRule=1, Code="kw", GoogleCode="-"}}, // Check plural
|
||||
/**/{"Corsican", new LanguageCodeDef {PluralRule=1, Code="co"}},
|
||||
/**/{"Cree", new LanguageCodeDef {PluralRule=1, Code="cr", GoogleCode="-"}},
|
||||
{"Croatian", new LanguageCodeDef {PluralRule=6, Code="hr"}},
|
||||
{"Croatian/Bosnia and Herzegovina", new LanguageCodeDef {PluralRule=5, Code="hr-BA", GoogleCode="hr"}},
|
||||
{"Czech", new LanguageCodeDef {PluralRule=7, Code="cs"}},
|
||||
{"Danish", new LanguageCodeDef {PluralRule=1, Code="da"}},
|
||||
/**/{"Divehi", new LanguageCodeDef {PluralRule=1, Code="dv", GoogleCode="-"}},
|
||||
{"Dutch", new LanguageCodeDef {PluralRule=1, Code="nl"}},
|
||||
{"Dutch/Belgium", new LanguageCodeDef {PluralRule=1, Code="nl-BE", GoogleCode="nl"}},
|
||||
{"Dutch/Netherlands", new LanguageCodeDef {PluralRule=1, Code="nl-NL", GoogleCode="nl"}},
|
||||
/**/{"Dzongkha", new LanguageCodeDef {PluralRule=1, Code="dz", GoogleCode="-"}},
|
||||
{"English", new LanguageCodeDef {PluralRule=1, Code="en"}},
|
||||
{"English/Australia", new LanguageCodeDef {PluralRule=1, Code="en-AU", GoogleCode="en"}},
|
||||
{"English/Belize", new LanguageCodeDef {PluralRule=1, Code="en-BZ", GoogleCode="en"}},
|
||||
{"English/Canada", new LanguageCodeDef {PluralRule=1, Code="en-CA", GoogleCode="en"}},
|
||||
{"English/Caribbean", new LanguageCodeDef {PluralRule=1, Code="en-CB", GoogleCode="en"}},
|
||||
{"English/Ireland", new LanguageCodeDef {PluralRule=1, Code="en-IE", GoogleCode="en"}},
|
||||
{"English/Jamaica", new LanguageCodeDef {PluralRule=1, Code="en-JM", GoogleCode="en"}},
|
||||
{"English/New Zealand", new LanguageCodeDef {PluralRule=1, Code="en-NZ", GoogleCode="en"}},
|
||||
{"English/Republic of the Philippines", new LanguageCodeDef {PluralRule=1, Code="en-PH", GoogleCode="en"}},
|
||||
{"English/South Africa",new LanguageCodeDef {PluralRule=1, Code="en-ZA", GoogleCode="en"}},
|
||||
{"English/Trinidad", new LanguageCodeDef {PluralRule=1, Code="en-TT", GoogleCode="en"}},
|
||||
{"English/United Kingdom",new LanguageCodeDef {PluralRule=1, Code="en-GB", GoogleCode="en"}},
|
||||
{"English/United States",new LanguageCodeDef {PluralRule=1, Code="en-US", GoogleCode="en"}},
|
||||
{"English/Zimbabwe", new LanguageCodeDef {PluralRule=1, Code="en-ZW", GoogleCode="en"}},
|
||||
{"Esperanto", new LanguageCodeDef {PluralRule=1, Code="eo"}},
|
||||
{"Estonian", new LanguageCodeDef {PluralRule=1, Code="et"}},
|
||||
/**/{"Ewe", new LanguageCodeDef {PluralRule=1, Code="ee", GoogleCode="-"}},
|
||||
{"Faeroese", new LanguageCodeDef {PluralRule=1, Code="fo", GoogleCode="-"}},
|
||||
/**/{"Fijian", new LanguageCodeDef {PluralRule=1, Code="fj", GoogleCode="-"}},
|
||||
//{"Filipino", new LanguageCodeDef(){PluralRule=2, Code="tl"}},
|
||||
{"Finnish", new LanguageCodeDef {PluralRule=1, Code="fi"}},
|
||||
{"French", new LanguageCodeDef {PluralRule=2, Code="fr"}},
|
||||
{"French/Belgium", new LanguageCodeDef {PluralRule=2, Code="fr-BE", GoogleCode="fr"}},
|
||||
{"French/Canada", new LanguageCodeDef {PluralRule=2, Code="fr-CA", GoogleCode="fr"}},
|
||||
{"French/France", new LanguageCodeDef {PluralRule=2, Code="fr-FR", GoogleCode="fr"}},
|
||||
{"French/Luxembourg", new LanguageCodeDef {PluralRule=2, Code="fr-LU", GoogleCode="fr"}},
|
||||
{"French/Principality of Monaco", new LanguageCodeDef {PluralRule=2, Code="fr-MC", GoogleCode="fr"}},
|
||||
{"French/Switzerland", new LanguageCodeDef {PluralRule=2, Code="fr-CH", GoogleCode="fr"}},
|
||||
/**/{"Fulah", new LanguageCodeDef {PluralRule=1, Code="ff", GoogleCode="-"}},
|
||||
{"Galician", new LanguageCodeDef {PluralRule=1, Code="gl"}},
|
||||
{"Galician/Spain", new LanguageCodeDef {PluralRule=1, Code="gl-ES", GoogleCode="gl"}},
|
||||
{"Georgian", new LanguageCodeDef {PluralRule=0, Code="ka"}},
|
||||
{"German", new LanguageCodeDef {PluralRule=1, Code="de"}},
|
||||
{"German/Austria", new LanguageCodeDef {PluralRule=1, Code="de-AT", GoogleCode="de"}},
|
||||
{"German/Germany", new LanguageCodeDef {PluralRule=1, Code="de-DE", GoogleCode="de"}},
|
||||
{"German/Liechtenstein",new LanguageCodeDef {PluralRule=1, Code="de-LI", GoogleCode="de"}},
|
||||
{"German/Luxembourg", new LanguageCodeDef {PluralRule=1, Code="de-LU", GoogleCode="de"}},
|
||||
{"German/Switzerland", new LanguageCodeDef {PluralRule=1, Code="de-CH", GoogleCode="de"}},
|
||||
{"Greek", new LanguageCodeDef {PluralRule=1, Code="el"}},
|
||||
/**/{"Guaraní", new LanguageCodeDef {PluralRule=1, Code="gn", GoogleCode="-"}},
|
||||
{"Gujarati", new LanguageCodeDef {PluralRule=1, Code="gu"}},
|
||||
/**/{"Haitian", new LanguageCodeDef {PluralRule=1, Code="ht"}},
|
||||
/**/{"Hausa", new LanguageCodeDef {PluralRule=1, Code="ha"}},
|
||||
{"Hebrew", new LanguageCodeDef {PluralRule=1, Code="he", GoogleCode="iw"}},
|
||||
/**/{"Herero", new LanguageCodeDef {PluralRule=1, Code="hz", GoogleCode="-"}},
|
||||
{"Hindi", new LanguageCodeDef {PluralRule=1, Code="hi"}},
|
||||
/**/{"Hiri Motu", new LanguageCodeDef {PluralRule=1, Code="ho", GoogleCode="-"}},
|
||||
{"Hungarian", new LanguageCodeDef {PluralRule=1, Code="hu"}},
|
||||
/**/{"Interlingua", new LanguageCodeDef {PluralRule=1, Code="ia", GoogleCode="-"}},
|
||||
{"Indonesian", new LanguageCodeDef {PluralRule=0, Code="id"}},
|
||||
/**/{"Interlingue", new LanguageCodeDef {PluralRule=1, Code="ie", GoogleCode="-"}},
|
||||
{"Irish", new LanguageCodeDef {PluralRule=10, Code="ga"}},
|
||||
/**/{"Igbo", new LanguageCodeDef {PluralRule=1, Code="ig"}},
|
||||
/**/{"Inupiaq", new LanguageCodeDef {PluralRule=1, Code="ik", GoogleCode="-"}},
|
||||
/**/{"Ido", new LanguageCodeDef {PluralRule=1, Code="io", GoogleCode="-"}},
|
||||
{"Icelandic", new LanguageCodeDef {PluralRule=14, Code="is"}},
|
||||
{"Italian", new LanguageCodeDef {PluralRule=1, Code="it"}},
|
||||
{"Italian/Italy", new LanguageCodeDef {PluralRule=1, Code="it-IT", GoogleCode="it"}},
|
||||
{"Italian/Switzerland", new LanguageCodeDef {PluralRule=1, Code="it-CH", GoogleCode="it"}},
|
||||
/**/{"Inuktitut", new LanguageCodeDef {PluralRule=1, Code="iu", GoogleCode="-"}},
|
||||
{"Japanese", new LanguageCodeDef {PluralRule=0, Code="ja", HasJoinedWords=true}},
|
||||
/**/{"Javanese", new LanguageCodeDef {PluralRule=1, Code="jv"}},
|
||||
/**/{"Kalaallisut", new LanguageCodeDef {PluralRule=1, Code="kl", GoogleCode="-"}},
|
||||
{"Kannada", new LanguageCodeDef {PluralRule=1, Code="kn"}},
|
||||
/**/{"Kanuri", new LanguageCodeDef {PluralRule=1, Code="kr", GoogleCode="-"}},
|
||||
/**/{"Kashmiri", new LanguageCodeDef {PluralRule=1, Code="ks", GoogleCode="-"}},
|
||||
{"Kazakh", new LanguageCodeDef {PluralRule=1, Code="kk"}},
|
||||
/**/{"Central Khmer", new LanguageCodeDef {PluralRule=1, Code="km"}},
|
||||
/**/{"Kikuyu", new LanguageCodeDef {PluralRule=1, Code="ki", GoogleCode="-"}},
|
||||
/**/{"Kinyarwanda", new LanguageCodeDef {PluralRule=1, Code="rw", GoogleCode="-"}},
|
||||
/**/{"Kirghiz", new LanguageCodeDef {PluralRule=1, Code="ky"}},
|
||||
/**/{"Komi", new LanguageCodeDef {PluralRule=1, Code="kv", GoogleCode="-"}},
|
||||
/**/{"Kongo", new LanguageCodeDef {PluralRule=1, Code="kg", GoogleCode="-"}},
|
||||
{"Korean", new LanguageCodeDef {PluralRule=0, Code="ko"}},
|
||||
{"Kurdish", new LanguageCodeDef {PluralRule=1, Code="ku"}},
|
||||
/**/{"Kuanyama", new LanguageCodeDef {PluralRule=1, Code="kj", GoogleCode="-"}},
|
||||
{"Latin", new LanguageCodeDef {PluralRule=1, Code="la"}},
|
||||
/**/{"Luxembourgish", new LanguageCodeDef {PluralRule=1, Code="lb"}},
|
||||
/**/{"Ganda", new LanguageCodeDef {PluralRule=1, Code="lg", GoogleCode="-"}},
|
||||
/**/{"Limburgan", new LanguageCodeDef {PluralRule=1, Code="li", GoogleCode="-"}},
|
||||
/**/{"Lingala", new LanguageCodeDef {PluralRule=1, Code="ln", GoogleCode="-"}},
|
||||
/**/{"Lao", new LanguageCodeDef {PluralRule=1, Code="lo"}},
|
||||
{"Latvian", new LanguageCodeDef {PluralRule=5, Code="lv"}},
|
||||
/**/{"Luba-Katanga", new LanguageCodeDef {PluralRule=1, Code="lu", GoogleCode="-"}},
|
||||
{"Lithuanian", new LanguageCodeDef {PluralRule=5, Code="lt"}},
|
||||
/**/{"Manx", new LanguageCodeDef {PluralRule=1, Code="gv", GoogleCode="-"}},
|
||||
{"Macedonian", new LanguageCodeDef {PluralRule=13, Code="mk"}},
|
||||
/**/{"Malagasy", new LanguageCodeDef {PluralRule=1, Code="mg"}},
|
||||
{"Malay", new LanguageCodeDef {PluralRule=0, Code="ms"}},
|
||||
{"Malay/Brunei Darussalam", new LanguageCodeDef {PluralRule=0, Code="ms-BN", GoogleCode="ms"}},
|
||||
{"Malay/Malaysia", new LanguageCodeDef {PluralRule=0, Code="ms-MY", GoogleCode="ms"}},
|
||||
{"Malayalam", new LanguageCodeDef {PluralRule=1, Code="ml"}},
|
||||
{"Maltese", new LanguageCodeDef {PluralRule=12, Code="mt"}},
|
||||
{"Maori", new LanguageCodeDef {PluralRule=2, Code="mi"}},
|
||||
{"Marathi", new LanguageCodeDef {PluralRule=1, Code="mr"}},
|
||||
/**/{"Marshallese", new LanguageCodeDef {PluralRule=1, Code="mh", GoogleCode="-"}},
|
||||
{"Mongolian", new LanguageCodeDef {PluralRule=1, Code="mn"}},
|
||||
/**/{"Nauru", new LanguageCodeDef {PluralRule=1, Code="na", GoogleCode="-"}},
|
||||
/**/{"Navajo", new LanguageCodeDef {PluralRule=1, Code="nv", GoogleCode="-"}},
|
||||
/**/{"North Ndebele", new LanguageCodeDef {PluralRule=1, Code="nd", GoogleCode="-"}},
|
||||
/**/{"Nepali", new LanguageCodeDef {PluralRule=1, Code="ne"}},
|
||||
/**/{"Ndonga", new LanguageCodeDef {PluralRule=1, Code="ng", GoogleCode="-"}},
|
||||
{"Northern Sotho", new LanguageCodeDef {PluralRule=1, Code="ns", GoogleCode="st"}},
|
||||
{"Norwegian", new LanguageCodeDef {PluralRule=1, Code="nb", GoogleCode="no"}},
|
||||
{"Norwegian/Nynorsk", new LanguageCodeDef {PluralRule=1, Code="nn", GoogleCode="no"}},
|
||||
/**/{"Sichuan Yi", new LanguageCodeDef {PluralRule=1, Code="ii", GoogleCode="-"}},
|
||||
/**/{"South Ndebele", new LanguageCodeDef {PluralRule=1, Code="nr", GoogleCode="-"}},
|
||||
/**/{"Occitan", new LanguageCodeDef {PluralRule=1, Code="oc", GoogleCode="-"}},
|
||||
/**/{"Ojibwa", new LanguageCodeDef {PluralRule=1, Code="oj", GoogleCode="-"}},
|
||||
/**/{"Church Slavic", new LanguageCodeDef {PluralRule=1, Code="cu", GoogleCode="-"}},
|
||||
/**/{"Oromo", new LanguageCodeDef {PluralRule=1, Code="om", GoogleCode="-"}},
|
||||
/**/{"Oriya", new LanguageCodeDef {PluralRule=1, Code="or", GoogleCode="-"}},
|
||||
/**/{"Ossetian", new LanguageCodeDef {PluralRule=1, Code="os", GoogleCode="-"}},
|
||||
/**/{"Pali", new LanguageCodeDef {PluralRule=1, Code="pi", GoogleCode="-"}},
|
||||
{"Pashto", new LanguageCodeDef {PluralRule=1, Code="ps"}},
|
||||
{"Persian", new LanguageCodeDef {PluralRule=0, Code="fa"}},
|
||||
{"Polish", new LanguageCodeDef {PluralRule=8, Code="pl"}},
|
||||
{"Portuguese", new LanguageCodeDef {PluralRule=1, Code="pt"}},
|
||||
{"Portuguese/Brazil", new LanguageCodeDef {PluralRule=2, Code="pt-BR", GoogleCode="pt"}},
|
||||
{"Portuguese/Portugal", new LanguageCodeDef {PluralRule=1, Code="pt-PT", GoogleCode="pt"}},
|
||||
{"Punjabi", new LanguageCodeDef {PluralRule=1, Code="pa"}},
|
||||
{"Quechua", new LanguageCodeDef {PluralRule=1, Code="qu", GoogleCode="-"}},
|
||||
{"Quechua/Bolivia", new LanguageCodeDef {PluralRule=1, Code="qu-BO", GoogleCode="-"}},
|
||||
{"Quechua/Ecuador", new LanguageCodeDef {PluralRule=1, Code="qu-EC", GoogleCode="-"}},
|
||||
{"Quechua/Peru", new LanguageCodeDef {PluralRule=1, Code="qu-PE", GoogleCode="-"}},
|
||||
{"Rhaeto-Romanic", new LanguageCodeDef {PluralRule=1, Code="rm", GoogleCode="ro"}},
|
||||
{"Romanian", new LanguageCodeDef {PluralRule=4, Code="ro"}},
|
||||
/**/{"Rundi", new LanguageCodeDef {PluralRule=1, Code="rn", GoogleCode="-"}},
|
||||
{"Russian", new LanguageCodeDef {PluralRule=6, Code="ru"}},
|
||||
{"Russian/Republic of Moldova", new LanguageCodeDef {PluralRule=6, Code="ru-MO", GoogleCode="ru"}},
|
||||
/**/{"Sanskrit", new LanguageCodeDef {PluralRule=1, Code="sa", GoogleCode="-"}},
|
||||
/**/{"Sardinian", new LanguageCodeDef {PluralRule=1, Code="sc", GoogleCode="-"}},
|
||||
/**/{"Sindhi", new LanguageCodeDef {PluralRule=1, Code="sd"}},
|
||||
/**/{"Northern Sami", new LanguageCodeDef {PluralRule=1, Code="se", GoogleCode="-"}},
|
||||
/**/{"Samoan", new LanguageCodeDef {PluralRule=1, Code="sm"}},
|
||||
/**/{"Sango", new LanguageCodeDef {PluralRule=1, Code="sg", GoogleCode="-"}},
|
||||
{"Serbian", new LanguageCodeDef {PluralRule=6, Code="sr"}},
|
||||
{"Serbian/Bosnia and Herzegovina", new LanguageCodeDef {PluralRule=5, Code="sr-BA", GoogleCode="sr"}},
|
||||
{"Serbian/Serbia and Montenegro", new LanguageCodeDef {PluralRule=5, Code="sr-SP", GoogleCode="sr"}},
|
||||
/**/{"Scottish Gaelic", new LanguageCodeDef {PluralRule=1, Code="gd"}},
|
||||
/**/{"Shona", new LanguageCodeDef {PluralRule=1, Code="sn"}},
|
||||
/**/{"Sinhala", new LanguageCodeDef {PluralRule=1, Code="si"}},
|
||||
{"Slovak", new LanguageCodeDef {PluralRule=7, Code="sk"}},
|
||||
{"Slovenian", new LanguageCodeDef {PluralRule=9, Code="sl"}},
|
||||
/**/{"Somali", new LanguageCodeDef {PluralRule=1, Code="so"}},
|
||||
/**/{"Southern Sotho", new LanguageCodeDef {PluralRule=1, Code="st"}},
|
||||
{"Spanish", new LanguageCodeDef {PluralRule=1, Code="es"}},
|
||||
{"Spanish/Argentina", new LanguageCodeDef {PluralRule=1, Code="es-AR", GoogleCode="es"}},
|
||||
{"Spanish/Bolivia", new LanguageCodeDef {PluralRule=1, Code="es-BO", GoogleCode="es"}},
|
||||
{"Spanish/Castilian", new LanguageCodeDef {PluralRule=1, Code="es-ES", GoogleCode="es"}},
|
||||
{"Spanish/Chile", new LanguageCodeDef {PluralRule=1, Code="es-CL", GoogleCode="es"}},
|
||||
{"Spanish/Colombia", new LanguageCodeDef {PluralRule=1, Code="es-CO", GoogleCode="es"}},
|
||||
{"Spanish/Costa Rica", new LanguageCodeDef {PluralRule=1, Code="es-CR", GoogleCode="es"}},
|
||||
{"Spanish/Dominican Republic", new LanguageCodeDef {PluralRule=1, Code="es-DO", GoogleCode="es"}},
|
||||
{"Spanish/Ecuador", new LanguageCodeDef {PluralRule=1, Code="es-EC", GoogleCode="es"}},
|
||||
{"Spanish/El Salvador", new LanguageCodeDef {PluralRule=1, Code="es-SV", GoogleCode="es"}},
|
||||
{"Spanish/Guatemala", new LanguageCodeDef {PluralRule=1, Code="es-GT", GoogleCode="es"}},
|
||||
{"Spanish/Honduras", new LanguageCodeDef {PluralRule=1, Code="es-HN", GoogleCode="es"}},
|
||||
{"Spanish/Mexico", new LanguageCodeDef {PluralRule=1, Code="es-MX", GoogleCode="es"}},
|
||||
{"Spanish/Nicaragua", new LanguageCodeDef {PluralRule=1, Code="es-NI", GoogleCode="es"}},
|
||||
{"Spanish/Panama", new LanguageCodeDef {PluralRule=1, Code="es-PA", GoogleCode="es"}},
|
||||
{"Spanish/Paraguay", new LanguageCodeDef {PluralRule=1, Code="es-PY", GoogleCode="es"}},
|
||||
{"Spanish/Peru", new LanguageCodeDef {PluralRule=1, Code="es-PE", GoogleCode="es"}},
|
||||
{"Spanish/Puerto Rico", new LanguageCodeDef {PluralRule=1, Code="es-PR", GoogleCode="es"}},
|
||||
{"Spanish/Spain", new LanguageCodeDef {PluralRule=1, Code="es-ES", GoogleCode="es"}},
|
||||
{"Spanish/Uruguay", new LanguageCodeDef {PluralRule=1, Code="es-UY", GoogleCode="es"}},
|
||||
{"Spanish/Venezuela", new LanguageCodeDef {PluralRule=1, Code="es-VE", GoogleCode="es"}},
|
||||
{"Spanish/Latin Americas", new LanguageCodeDef {PluralRule=1, Code="es-US", GoogleCode="es"}},
|
||||
/**/{"Sundanese", new LanguageCodeDef {PluralRule=1, Code="su"}},
|
||||
{"Swahili", new LanguageCodeDef {Code="sw"}},
|
||||
/**/{"Swati", new LanguageCodeDef {PluralRule=1, Code="ss", GoogleCode="-"}},
|
||||
{"Swedish", new LanguageCodeDef {PluralRule=1, Code="sv"}},
|
||||
{"Swedish/Finland", new LanguageCodeDef {PluralRule=1, Code="sv-FI", GoogleCode="sv"}},
|
||||
{"Swedish/Sweden", new LanguageCodeDef {PluralRule=1, Code="sv-SE", GoogleCode="sv"}},
|
||||
{"Tamil", new LanguageCodeDef {PluralRule=1, Code="ta"}},
|
||||
{"Tatar", new LanguageCodeDef {PluralRule=0, Code="tt", GoogleCode="-"}},
|
||||
{"Telugu", new LanguageCodeDef {PluralRule=1, Code="te"}},
|
||||
/**/{"Tajik", new LanguageCodeDef {PluralRule=1, Code="tg"}},
|
||||
{"Thai", new LanguageCodeDef {PluralRule=0, Code="th", HasJoinedWords=true}},
|
||||
/**/{"Tigrinya", new LanguageCodeDef {PluralRule=1, Code="ti", GoogleCode="-"}},
|
||||
/**/{"Tibetan", new LanguageCodeDef {PluralRule=1, Code="bo", GoogleCode="-"}},
|
||||
/**/{"Turkmen", new LanguageCodeDef {PluralRule=1, Code="tk", GoogleCode="-"}},
|
||||
/**/{"Tagalog", new LanguageCodeDef {PluralRule=1, Code="tl"}},
|
||||
/**/{"Tswana", new LanguageCodeDef {PluralRule=1, Code="tn", GoogleCode="-"}},
|
||||
/**/{"Tonga", new LanguageCodeDef {PluralRule=1, Code="to", GoogleCode="-"}},
|
||||
{"Turkish", new LanguageCodeDef {PluralRule=0, Code="tr"}},
|
||||
/**/{"Tsonga", new LanguageCodeDef {PluralRule=1, Code="ts", GoogleCode="-"}},
|
||||
/**/{"Twi", new LanguageCodeDef {PluralRule=1, Code="tw", GoogleCode="-"}},
|
||||
/**/{"Tahitian", new LanguageCodeDef {PluralRule=1, Code="ty", GoogleCode="-"}},
|
||||
/**/{"Uighur", new LanguageCodeDef {PluralRule=1, Code="ug", GoogleCode="-"}},
|
||||
{"Ukrainian", new LanguageCodeDef {PluralRule=6, Code="uk"}},
|
||||
{"Urdu", new LanguageCodeDef {PluralRule=1, Code="ur"}},
|
||||
{"Uzbek", new LanguageCodeDef {PluralRule=2, Code="uz"}},
|
||||
/**/{"Venda", new LanguageCodeDef {PluralRule=1, Code="ve", GoogleCode="-"}},
|
||||
{"Vietnamese", new LanguageCodeDef {PluralRule=1, Code="vi"}},
|
||||
/**/{"Volapük", new LanguageCodeDef {PluralRule=1, Code="vo", GoogleCode="-"}},
|
||||
/**/{"Walloon", new LanguageCodeDef {PluralRule=1, Code="wa", GoogleCode="-"}},
|
||||
{"Welsh", new LanguageCodeDef {PluralRule=16, Code="cy"}},
|
||||
/**/{"Wolof", new LanguageCodeDef {PluralRule=1, Code="wo", GoogleCode="-"}},
|
||||
/**/{"Frisian", new LanguageCodeDef {PluralRule=1, Code="fy"}},
|
||||
{"Xhosa", new LanguageCodeDef {PluralRule=1, Code="xh"}},
|
||||
{"Yiddish", new LanguageCodeDef {PluralRule=1, Code="yi"}},
|
||||
/**/{"Yoruba", new LanguageCodeDef {PluralRule=1, Code="yo"}},
|
||||
/**/{"Zhuang", new LanguageCodeDef {PluralRule=1, Code="za", GoogleCode="-"}},
|
||||
{"Zulu", new LanguageCodeDef {PluralRule=1, Code="zu"}}
|
||||
};
|
||||
|
||||
static int GetPluralRule( string langCode )
|
||||
{
|
||||
if (langCode.Length > 2)
|
||||
langCode = langCode.Substring(0, 2);
|
||||
langCode = langCode.ToLower();
|
||||
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (kvp.Value.Code == langCode)
|
||||
{
|
||||
return kvp.Value.PluralRule;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
|
||||
//http://cldr.unicode.org/cldr-features#TOC-Locale-specific-patterns-for-formatting-and-parsing:
|
||||
//http://cldr.unicode.org/index/cldr-spec/plural-rules
|
||||
public static bool LanguageHasPluralType( string langCode, string pluralType )
|
||||
{
|
||||
if (pluralType == "Plural" || pluralType=="Zero" || pluralType=="One")
|
||||
return true;
|
||||
|
||||
int rule = GetPluralRule (langCode);
|
||||
|
||||
switch (rule)
|
||||
{
|
||||
case 3: // Celtic (Scottish Gaelic)
|
||||
return pluralType=="Two" || pluralType=="Few";
|
||||
|
||||
case 4: // Families: Romanic (Romanian)
|
||||
case 5: // Families: Baltic (Latvian, Lithuanian)
|
||||
case 6: // Families: Slavic (Belarusian, Bosnian, Croatian, Serbian, Russian, Ukrainian)
|
||||
case 7: // Families: Slavic (Slovak, Czech)
|
||||
case 8: // Families: Slavic (Polish)
|
||||
return pluralType=="Few";
|
||||
|
||||
case 9: // Families: Slavic (Slovenian, Sorbian)
|
||||
return pluralType=="Two" || pluralType=="Few";
|
||||
|
||||
case 10: // Families: Celtic (Irish Gaelic)
|
||||
case 11: // Families: Semitic (Arabic)
|
||||
case 15: // Families: Celtic (Breton)
|
||||
case 16: // Families: (Welsh)
|
||||
return pluralType=="Two" || pluralType=="Few" || pluralType=="Many";
|
||||
|
||||
case 12: // Families: Semitic (Maltese)
|
||||
return pluralType=="Few" || pluralType=="Many";
|
||||
|
||||
case 13: // Families: Slavic (Macedonian)
|
||||
return pluralType=="Two";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals
|
||||
public static ePluralType GetPluralType( string langCode, int n )
|
||||
{
|
||||
if (n == 0) return ePluralType.Zero;
|
||||
if (n == 1) return ePluralType.One;
|
||||
|
||||
int rule = GetPluralRule (langCode);
|
||||
|
||||
switch (rule)
|
||||
{
|
||||
case 0: // Families: Asian (Chinese, Japanese, Korean), Persian, Turkic/Altaic (Turkish), Thai, Lao
|
||||
return ePluralType.Plural;
|
||||
|
||||
case 1: // Families: Germanic (Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish), Finno-Ugric (Estonian, Finnish, Hungarian), Language isolate (Basque), Latin/Greek (Greek), Semitic (Hebrew), Romanic (Italian, Portuguese, Spanish, Catalan), Vietnamese
|
||||
return n==1 ? ePluralType.One : ePluralType.Plural;
|
||||
|
||||
case 2: // Families: Romanic (French, Brazilian Portuguese)
|
||||
return n<=1 ? ePluralType.One : ePluralType.Plural;
|
||||
|
||||
case 3: // Celtic (Scottish Gaelic)
|
||||
return n==1 || n==11 ? ePluralType.One :
|
||||
n==2 || n==12 ? ePluralType.Two :
|
||||
inRange(n,3,10) || inRange(n,13,19) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 4: // Families: Romanic (Romanian)
|
||||
return n==1 ? ePluralType.One :
|
||||
inRange(n%100, 1, 19) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 5: // Families: Baltic (Latvian, Lithuanian)
|
||||
return n%10==1 && n%100!=11 ? ePluralType.One :
|
||||
n%10>=2 && (n%100<10 || n%100>=20) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 6: // Families: Slavic (Belarusian, Bosnian, Croatian, Serbian, Russian, Ukrainian)
|
||||
return n % 10 == 1 && n % 100 != 11 ? ePluralType.One :
|
||||
inRange (n%10,2,4) && !inRange (n%100,12,14) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 7: // Families: Slavic (Slovak, Czech)
|
||||
return n==1 ? ePluralType.One :
|
||||
inRange(n,2,4) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 8: // Families: Slavic (Polish)
|
||||
return n==1 ? ePluralType.One :
|
||||
inRange (n%10,2,4) && !inRange (n%100,12,14) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 9: // Families: Slavic (Slovenian, Sorbian)
|
||||
return n%100==1 ? ePluralType.One :
|
||||
n%100==2 ? ePluralType.Two :
|
||||
inRange(n%100,3,4) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 10: // Families: Celtic (Irish Gaelic)
|
||||
return n==1 ? ePluralType.One :
|
||||
n==2 ? ePluralType.Two :
|
||||
inRange(n, 3,6) ? ePluralType.Few :
|
||||
inRange(n, 7,10)? ePluralType.Many : ePluralType.Plural;
|
||||
|
||||
case 11: // Families: Semitic (Arabic)
|
||||
return n==0 ? ePluralType.Zero :
|
||||
n==1 ? ePluralType.One :
|
||||
n==2 ? ePluralType.Two :
|
||||
inRange(n%100,3,10) ? ePluralType.Few :
|
||||
n%100>=11 ? ePluralType.Many : ePluralType.Plural;
|
||||
|
||||
case 12: // Families: Semitic (Maltese)
|
||||
return n==1 ? ePluralType.One :
|
||||
inRange(n%100, 1, 10) ? ePluralType.Few :
|
||||
inRange(n%100, 11,19) ? ePluralType.Many : ePluralType.Plural;
|
||||
|
||||
case 13: // Families: Slavic (Macedonian)
|
||||
return n % 10 == 1 ? ePluralType.One :
|
||||
n % 10 == 2 ? ePluralType.Two : ePluralType.Plural;
|
||||
|
||||
case 14: // Plural rule #15 (2 forms)
|
||||
return n%10==1 && n%100!=11 ? ePluralType.One : ePluralType.Plural;
|
||||
|
||||
case 15: // Families: Celtic (Breton)
|
||||
return n % 10 == 1 && n % 100 != 11 && n % 100 != 71 && n % 100 != 91 ? ePluralType.One :
|
||||
n % 10 == 2 && n % 100 != 12 && n % 100 != 72 && n % 100 != 92 ? ePluralType.Two :
|
||||
(n % 10 == 3 || n % 10 == 4 || n % 10 == 9) && n % 100 != 13 && n % 100 != 14 && n % 100 != 19 && n % 100 != 73 && n % 100 != 74 && n % 100 != 79 && n % 100 != 93 && n % 100 != 94 && n % 100 != 99 ? ePluralType.Few :
|
||||
n%1000000==0 ? ePluralType.Many : ePluralType.Plural;
|
||||
|
||||
case 16: // Families: (Welsh)
|
||||
return n==0 ? ePluralType.Zero :
|
||||
n==1 ? ePluralType.One :
|
||||
n==2 ? ePluralType.Two :
|
||||
n==3 ? ePluralType.Few :
|
||||
n==6 ? ePluralType.Many : ePluralType.Plural;
|
||||
|
||||
}
|
||||
|
||||
return ePluralType.Plural;
|
||||
}
|
||||
|
||||
// A number that belong to the pluralType form
|
||||
public static int GetPluralTestNumber( string langCode, ePluralType pluralType )
|
||||
{
|
||||
switch (pluralType)
|
||||
{
|
||||
case ePluralType.Zero:
|
||||
return 0;
|
||||
|
||||
case ePluralType.One:
|
||||
return 1;
|
||||
|
||||
case ePluralType.Few:
|
||||
return 3;
|
||||
|
||||
case ePluralType.Many:
|
||||
{
|
||||
int rule = GetPluralRule (langCode);
|
||||
if (rule == 10) return 8;
|
||||
if (rule == 11 || rule==12) return 13;
|
||||
if (rule == 15) return 1000000;
|
||||
return 6;
|
||||
}
|
||||
|
||||
default:
|
||||
return 936;
|
||||
}
|
||||
}
|
||||
|
||||
static bool inRange(int amount, int min, int max)
|
||||
{
|
||||
return amount >= min && amount <= max;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26e29b3e77176de4cbb64a3ec85beee6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,86 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
public static partial class GoogleTranslation
|
||||
{
|
||||
public delegate void fnOnTranslated(string Translation, string Error);
|
||||
|
||||
public static bool CanTranslate ()
|
||||
{
|
||||
return LocalizationManager.Sources.Count > 0 &&
|
||||
!string.IsNullOrEmpty (LocalizationManager.GetWebServiceURL());
|
||||
}
|
||||
|
||||
|
||||
// LanguageCodeFrom can be "auto"
|
||||
// After the translation is returned from Google, it will call OnTranslationReady(TranslationResult, ErrorMsg)
|
||||
// TranslationResult will be null if translation failed
|
||||
public static void Translate( string text, string LanguageCodeFrom, string LanguageCodeTo, fnOnTranslated OnTranslationReady )
|
||||
{
|
||||
LocalizationManager.InitializeIfNeeded();
|
||||
if (!CanTranslate())
|
||||
{
|
||||
OnTranslationReady(null, "WebService is not set correctly or needs to be reinstalled");
|
||||
return;
|
||||
}
|
||||
//LanguageCodeTo = GoogleLanguages.GetGoogleLanguageCode(LanguageCodeTo);
|
||||
|
||||
if (LanguageCodeTo==LanguageCodeFrom)
|
||||
{
|
||||
OnTranslationReady(text, null);
|
||||
return;
|
||||
}
|
||||
|
||||
TranslationDictionary queries = new TranslationDictionary(System.StringComparer.Ordinal);
|
||||
|
||||
|
||||
// Unsupported language
|
||||
if (string.IsNullOrEmpty(LanguageCodeTo))
|
||||
{
|
||||
OnTranslationReady(string.Empty, null);
|
||||
return;
|
||||
}
|
||||
CreateQueries(text, LanguageCodeFrom, LanguageCodeTo, queries); // can split plurals and specializations into several queries
|
||||
|
||||
Translate(queries, (results,error)=>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(error) || results.Count==0)
|
||||
{
|
||||
OnTranslationReady(null, error);
|
||||
return;
|
||||
}
|
||||
|
||||
string result = RebuildTranslation( text, queries, LanguageCodeTo); // gets the result from google and rebuilds the text from multiple queries if its is plurals
|
||||
OnTranslationReady( result, null );
|
||||
});
|
||||
}
|
||||
|
||||
// Query google for the translation and waits until google returns
|
||||
// On some Unity versions (e.g. 2017.1f1) unity doesn't handle well waiting for WWW in the main thread, so this call can fail
|
||||
// In those cases, its advisable to use the Async version (GoogleTranslation.Translate(....))
|
||||
public static string ForceTranslate ( string text, string LanguageCodeFrom, string LanguageCodeTo )
|
||||
{
|
||||
TranslationDictionary dict = new TranslationDictionary(System.StringComparer.Ordinal);
|
||||
AddQuery(text, LanguageCodeFrom, LanguageCodeTo, dict);
|
||||
|
||||
var job = new TranslationJob_Main(dict, null);
|
||||
while (true)
|
||||
{
|
||||
var state = job.GetState();
|
||||
if (state == TranslationJob.eJobState.Running)
|
||||
continue;
|
||||
|
||||
if (state == TranslationJob.eJobState.Failed)
|
||||
return null;
|
||||
|
||||
//TranslationJob.eJobState.Succeeded
|
||||
return GetQueryResult( text, "", dict);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc4d0073f9e452047bd31b01de2bbd82
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
|
||||
public static partial class GoogleTranslation
|
||||
{
|
||||
static List<UnityWebRequest> mCurrentTranslations = new List<UnityWebRequest>();
|
||||
static List<TranslationJob> mTranslationJobs = new List<TranslationJob>();
|
||||
|
||||
public delegate void fnOnTranslationReady(TranslationDictionary dict, string error);
|
||||
|
||||
#region Multiple Translations
|
||||
|
||||
public static void Translate( TranslationDictionary requests, fnOnTranslationReady OnTranslationReady, bool usePOST = true )
|
||||
{
|
||||
//WWW www = GetTranslationWWW( requests, usePOST );
|
||||
//I2.Loc.CoroutineManager.Start(WaitForTranslation(www, OnTranslationReady, requests));
|
||||
AddTranslationJob( new TranslationJob_Main(requests, OnTranslationReady) );
|
||||
}
|
||||
|
||||
public static bool ForceTranslate(TranslationDictionary requests, bool usePOST = true)
|
||||
{
|
||||
var job = new TranslationJob_Main(requests, null);
|
||||
while (true)
|
||||
{
|
||||
var state = job.GetState();
|
||||
if (state == TranslationJob.eJobState.Running)
|
||||
continue;
|
||||
|
||||
if (state == TranslationJob.eJobState.Failed)
|
||||
return false;
|
||||
|
||||
//TranslationJob.eJobState.Succeeded
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<string> ConvertTranslationRequest(TranslationDictionary requests, bool encodeGET)
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (var kvp in requests)
|
||||
{
|
||||
var request = kvp.Value;
|
||||
if (sb.Length > 0)
|
||||
sb.Append("<I2Loc>");
|
||||
|
||||
sb.Append(GoogleLanguages.GetGoogleLanguageCode(request.LanguageCode));
|
||||
sb.Append(":");
|
||||
for (int i = 0; i < request.TargetLanguagesCode.Length; ++i)
|
||||
{
|
||||
if (i != 0) sb.Append(",");
|
||||
sb.Append(GoogleLanguages.GetGoogleLanguageCode(request.TargetLanguagesCode[i]));
|
||||
}
|
||||
sb.Append("=");
|
||||
|
||||
var text = TitleCase(request.Text) == request.Text ? request.Text.ToLowerInvariant() : request.Text;
|
||||
|
||||
if (!encodeGET)
|
||||
{
|
||||
sb.Append(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(Uri.EscapeDataString(text));
|
||||
if (sb.Length > 4000)
|
||||
{
|
||||
results.Add(sb.ToString());
|
||||
sb.Length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
results.Add(sb.ToString());
|
||||
return results;
|
||||
}
|
||||
|
||||
static void AddTranslationJob( TranslationJob job )
|
||||
{
|
||||
mTranslationJobs.Add(job);
|
||||
if (mTranslationJobs.Count==1)
|
||||
{
|
||||
CoroutineManager.Start(WaitForTranslations());
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerator WaitForTranslations()
|
||||
{
|
||||
while (mTranslationJobs.Count > 0)
|
||||
{
|
||||
var jobs = mTranslationJobs.ToArray();
|
||||
foreach (var job in jobs)
|
||||
{
|
||||
if (job.GetState() != TranslationJob.eJobState.Running)
|
||||
mTranslationJobs.Remove(job);
|
||||
}
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static string ParseTranslationResult( string html, TranslationDictionary requests )
|
||||
{
|
||||
//Debug.Log(html);
|
||||
// Handle google restricting the webservice to run
|
||||
if (html.StartsWith("<!DOCTYPE html>") || html.StartsWith("<HTML>"))
|
||||
{
|
||||
if (html.Contains("The script completed but did not return anything"))
|
||||
return "The current Google WebService is not supported.\nPlease, delete the WebService from the Google Drive and Install the latest version.";
|
||||
if (html.Contains("Service invoked too many times in a short time"))
|
||||
return ""; // ignore and try again
|
||||
return "There was a problem contacting the WebService. Please try again later\n" + html;
|
||||
}
|
||||
|
||||
string[] texts = html.Split (new[]{"<I2Loc>"}, StringSplitOptions.None);
|
||||
string[] splitter = {"<i2>"};
|
||||
int i = 0;
|
||||
|
||||
var Keys = requests.Keys.ToArray();
|
||||
foreach (var text in Keys)
|
||||
{
|
||||
var temp = FindQueryFromOrigText(text, requests);
|
||||
var fullText = texts[i++];
|
||||
if (temp.Tags != null)
|
||||
{
|
||||
//for (int j = 0, jmax = temp.Tags.Length; j < jmax; ++j)
|
||||
for (int j = temp.Tags.Length-1; j>=0; --j)
|
||||
{
|
||||
fullText = fullText.Replace(GetGoogleNoTranslateTag(j), temp.Tags[j]);
|
||||
//fullText = fullText.Replace( /*"{[" + j + "]}"*/ ((char)(0x2600+j)).ToString(), temp.Tags[j]);
|
||||
}
|
||||
}
|
||||
|
||||
temp.Results = fullText.Split (splitter, StringSplitOptions.None);
|
||||
|
||||
// Google has problem translating this "This Is An Example" but not this "this is an example"
|
||||
if (TitleCase(text)==text)
|
||||
{
|
||||
for (int j=0; j<temp.Results.Length; ++j)
|
||||
temp.Results[j] = TitleCase(temp.Results[j]);
|
||||
}
|
||||
requests[temp.OrigText] = temp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static bool IsTranslating()
|
||||
{
|
||||
return mCurrentTranslations.Count>0 || mTranslationJobs.Count > 0;
|
||||
}
|
||||
|
||||
public static void CancelCurrentGoogleTranslations()
|
||||
{
|
||||
mCurrentTranslations.Clear ();
|
||||
foreach (var job in mTranslationJobs)
|
||||
{
|
||||
job.Dispose();
|
||||
}
|
||||
mTranslationJobs.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94b94d27ab6931c4abee1e4d3655b660
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,375 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
public struct TranslationQuery
|
||||
{
|
||||
public string OrigText;
|
||||
public string Text; // Text without Tags
|
||||
public string LanguageCode;
|
||||
public string[] TargetLanguagesCode;
|
||||
public string[] Results; // This is filled google returns the translations
|
||||
public string[] Tags; // This are the sections of the orignal text that shoudn't be translated
|
||||
}
|
||||
|
||||
public static partial class GoogleTranslation
|
||||
{
|
||||
public static void CreateQueries(string text, string LanguageCodeFrom, string LanguageCodeTo, TranslationDictionary dict)
|
||||
{
|
||||
if (!text.Contains("[i2s_"))
|
||||
{
|
||||
CreateQueries_Plurals(text, LanguageCodeFrom, LanguageCodeTo, dict);
|
||||
return;
|
||||
}
|
||||
|
||||
var variants = SpecializationManager.GetSpecializations(text);
|
||||
foreach (var kvp in variants)
|
||||
{
|
||||
CreateQueries_Plurals(kvp.Value, LanguageCodeFrom, LanguageCodeTo, dict);
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateQueries_Plurals(string text, string LanguageCodeFrom, string LanguageCodeTo, TranslationDictionary dict)
|
||||
{
|
||||
bool hasPluralParams = text.Contains("{[#");
|
||||
bool hasPluralTypes = text.Contains("[i2p_");
|
||||
if (!HasParameters(text) || !hasPluralParams && !hasPluralTypes)
|
||||
{
|
||||
AddQuery(text, LanguageCodeFrom, LanguageCodeTo, dict);
|
||||
return;
|
||||
}
|
||||
|
||||
bool forcePluralParam = hasPluralParams;
|
||||
|
||||
for (var i = (ePluralType)0; i <= ePluralType.Plural; ++i)
|
||||
{
|
||||
var pluralType = i.ToString();
|
||||
if (!GoogleLanguages.LanguageHasPluralType(LanguageCodeTo, pluralType))
|
||||
continue;
|
||||
|
||||
var newText = GetPluralText(text, pluralType);
|
||||
int testNumber = GoogleLanguages.GetPluralTestNumber(LanguageCodeTo, i);
|
||||
|
||||
var parameter = GetPluralParameter(newText, forcePluralParam);
|
||||
if (!string.IsNullOrEmpty(parameter))
|
||||
newText = newText.Replace(parameter, testNumber.ToString());
|
||||
|
||||
//Debug.Log("Translate: " + newText);
|
||||
|
||||
AddQuery(newText, LanguageCodeFrom, LanguageCodeTo, dict);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddQuery(string text, string LanguageCodeFrom, string LanguageCodeTo, TranslationDictionary dict)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return;
|
||||
|
||||
|
||||
if (!dict.ContainsKey(text))
|
||||
{
|
||||
var query = new TranslationQuery { OrigText = text, LanguageCode = LanguageCodeFrom, TargetLanguagesCode = new[] { LanguageCodeTo } };
|
||||
query.Text = text;
|
||||
ParseNonTranslatableElements(ref query);
|
||||
dict[text] = query;
|
||||
}
|
||||
else
|
||||
{
|
||||
var query = dict[text];
|
||||
if (Array.IndexOf(query.TargetLanguagesCode, LanguageCodeTo) < 0)
|
||||
{
|
||||
query.TargetLanguagesCode = query.TargetLanguagesCode.Concat(new[] { LanguageCodeTo }).Distinct().ToArray();
|
||||
}
|
||||
dict[text] = query;
|
||||
}
|
||||
}
|
||||
|
||||
static string GetTranslation(string text, string LanguageCodeTo, TranslationDictionary dict)
|
||||
{
|
||||
if (!dict.ContainsKey(text))
|
||||
return null;
|
||||
var query = dict[text];
|
||||
|
||||
int langIdx = Array.IndexOf(query.TargetLanguagesCode, LanguageCodeTo);
|
||||
if (langIdx < 0)
|
||||
return "";
|
||||
|
||||
if (query.Results == null)
|
||||
return "";
|
||||
return query.Results[langIdx];
|
||||
}
|
||||
|
||||
static TranslationQuery FindQueryFromOrigText(string origText, TranslationDictionary dict)
|
||||
{
|
||||
foreach (var kvp in dict)
|
||||
{
|
||||
if (kvp.Value.OrigText == origText)
|
||||
return kvp.Value;
|
||||
}
|
||||
return default(TranslationQuery);
|
||||
}
|
||||
|
||||
public static bool HasParameters( string text )
|
||||
{
|
||||
int idx = text.IndexOf("{[", StringComparison.Ordinal);
|
||||
if (idx < 0) return false;
|
||||
return text.IndexOf("]}", idx, StringComparison.Ordinal) > 0;
|
||||
}
|
||||
|
||||
public static string GetPluralParameter(string text, bool forceTag) // force tag requires that the parameter has the form {[#param]}
|
||||
{
|
||||
// Try finding the "plural parameter" that has the form {[#name]}
|
||||
// this allows using the second parameter as plural: "Player {[name1]} has {[#value]} points"
|
||||
int idx0 = text.IndexOf("{[#", StringComparison.Ordinal);
|
||||
if (idx0 < 0)
|
||||
{
|
||||
if (forceTag) return null;
|
||||
idx0 = text.IndexOf("{[", StringComparison.Ordinal); // fallback to the first paremeter if no one has the # tag
|
||||
}
|
||||
if (idx0 < 0)
|
||||
return null;
|
||||
|
||||
int idx1 = text.IndexOf("]}", idx0+2, StringComparison.Ordinal);
|
||||
if (idx1 < 0)
|
||||
return null; // no closing parameter tag
|
||||
|
||||
return text.Substring(idx0, idx1 - idx0 + 2);
|
||||
}
|
||||
|
||||
public static string GetPluralText( string text, string pluralType )
|
||||
{
|
||||
pluralType = "[i2p_" + pluralType + "]";
|
||||
int idx0 = text.IndexOf(pluralType, StringComparison.Ordinal);
|
||||
if (idx0>=0)
|
||||
{
|
||||
idx0 += pluralType.Length;
|
||||
int idx1 = text.IndexOf("[i2p_",idx0, StringComparison.Ordinal);
|
||||
if (idx1 < 0) idx1 = text.Length;
|
||||
|
||||
return text.Substring(idx0, idx1 - idx0);
|
||||
}
|
||||
|
||||
// PluralType not found, fallback to the first one
|
||||
idx0 = text.IndexOf("[i2p_", StringComparison.Ordinal);
|
||||
if (idx0 < 0)
|
||||
return text; // No plural tags: "my text"
|
||||
|
||||
if (idx0>0)
|
||||
return text.Substring(0, idx0); // Case: "my text[i2p_zero]hello"
|
||||
|
||||
// Case: "[i2p_plural]my text[i2p_zero]hello"
|
||||
idx0 = text.IndexOf("]", StringComparison.Ordinal);
|
||||
if (idx0 < 0) return text; // starts like a plural, but has none
|
||||
|
||||
idx0 += 1;
|
||||
int idx2 = text.IndexOf("[i2p_", idx0, StringComparison.Ordinal);
|
||||
if (idx2 < 0) idx2 = text.Length;
|
||||
return text.Substring(idx0, idx2 - idx0);
|
||||
}
|
||||
|
||||
static int FindClosingTag(string tag, MatchCollection matches, int startIndex)
|
||||
{
|
||||
for (int i = startIndex, imax = matches.Count; i < imax; ++i)
|
||||
{
|
||||
var newTag = I2Utils.GetCaptureMatch(matches[i]);
|
||||
if (newTag[0]=='/' && tag.StartsWith(newTag.Substring(1), StringComparison.Ordinal))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static string GetGoogleNoTranslateTag(int tagNumber)
|
||||
{
|
||||
//return " I2NT" + tagNumber;
|
||||
if (tagNumber < 70)
|
||||
return "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++".Substring(0, tagNumber+1);
|
||||
|
||||
string s = "";
|
||||
for (int i = -1; i < tagNumber; ++i)
|
||||
s += "+";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
static void ParseNonTranslatableElements( ref TranslationQuery query )
|
||||
{
|
||||
//\[i2nt].*\[\/i2nt]
|
||||
var matches = Regex.Matches( query.Text, @"\{\[(.*?)]}|\[(.*?)]|\<(.*?)>");
|
||||
if (matches == null || matches.Count == 0)
|
||||
return;
|
||||
|
||||
string finalText = query.Text;
|
||||
List<string> finalTags = new List<string>();
|
||||
for (int i=0, imax=matches.Count; i<imax; ++i)
|
||||
{
|
||||
var tag = I2Utils.GetCaptureMatch( matches[i] );
|
||||
int iClosingTag = FindClosingTag(tag, matches, i); // find [/tag] or </tag>
|
||||
|
||||
if (iClosingTag < 0)
|
||||
{
|
||||
// Its not a tag, its a parameter
|
||||
var fulltag = matches[i].ToString();
|
||||
if (fulltag.StartsWith("{[", StringComparison.Ordinal) && fulltag.EndsWith("]}", StringComparison.Ordinal))
|
||||
{
|
||||
finalText = finalText.Replace(fulltag, GetGoogleNoTranslateTag(finalTags.Count)+" "); // 0x2600 is the start of the UNICODE Miscellaneous Symbols table, so they are not going to be translated by google
|
||||
//finalText = finalText.Replace(fulltag, /*"{[" + finalTags.Count + "]}"*/ ((char)(0x2600 + finalTags.Count)).ToString()); // 0x2600 is the start of the UNICODE Miscellaneous Symbols table, so they are not going to be translated by google
|
||||
finalTags.Add(fulltag);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tag == "i2nt")
|
||||
{
|
||||
var tag1 = query.Text.Substring(matches[i].Index, matches[iClosingTag].Index-matches[i].Index + matches[iClosingTag].Length);
|
||||
finalText = finalText.Replace(tag1, GetGoogleNoTranslateTag(finalTags.Count)+" ");
|
||||
//finalText = finalText.Replace(tag1, /*"{[" + finalTags.Count + "]}"*/ ((char)(0x2600 + finalTags.Count)).ToString());
|
||||
|
||||
finalTags.Add(tag1);
|
||||
}
|
||||
else
|
||||
{
|
||||
var tag1 = matches[i].ToString();
|
||||
finalText = finalText.Replace(tag1, GetGoogleNoTranslateTag(finalTags.Count)+" ");
|
||||
//finalText = finalText.Replace(tag1, /*"{[" + finalTags.Count + "]}"*/ ((char)(0x2600 + finalTags.Count)).ToString());
|
||||
finalTags.Add(tag1);
|
||||
|
||||
var tag2 = matches[iClosingTag].ToString();
|
||||
finalText = finalText.Replace(tag2, GetGoogleNoTranslateTag(finalTags.Count)+" ");
|
||||
//finalText = finalText.Replace(tag2, /*"{[" + finalTags.Count + "]}"*/ ((char)(0x2600 + finalTags.Count)).ToString());
|
||||
finalTags.Add(tag2);
|
||||
}
|
||||
}
|
||||
|
||||
query.Text = finalText;
|
||||
query.Tags = finalTags.ToArray();
|
||||
}
|
||||
|
||||
public static string GetQueryResult(string text, string LanguageCodeTo, TranslationDictionary dict)
|
||||
{
|
||||
if (!dict.ContainsKey(text))
|
||||
return null;
|
||||
|
||||
var query = dict[text];
|
||||
if (query.Results == null || query.Results.Length < 0)
|
||||
return null;
|
||||
|
||||
if (string.IsNullOrEmpty(LanguageCodeTo))
|
||||
return query.Results[0];
|
||||
|
||||
int idx = Array.IndexOf(query.TargetLanguagesCode, LanguageCodeTo);
|
||||
if (idx < 0)
|
||||
return null;
|
||||
|
||||
return query.Results[idx];
|
||||
}
|
||||
|
||||
public static string RebuildTranslation(string text, TranslationDictionary dict, string LanguageCodeTo)
|
||||
{
|
||||
if (!text.Contains("[i2s_"))
|
||||
{
|
||||
return RebuildTranslation_Plural(text, dict, LanguageCodeTo);
|
||||
}
|
||||
|
||||
var variants = SpecializationManager.GetSpecializations(text);
|
||||
var results = new Dictionary<string,string>(StringComparer.Ordinal);
|
||||
|
||||
foreach (var kvp in variants)
|
||||
{
|
||||
results[kvp.Key] = RebuildTranslation_Plural(kvp.Value, dict, LanguageCodeTo);
|
||||
}
|
||||
return SpecializationManager.SetSpecializedText(results);
|
||||
}
|
||||
|
||||
static string RebuildTranslation_Plural( string text, TranslationDictionary dict, string LanguageCodeTo )
|
||||
{
|
||||
bool hasPluralParams = text.Contains("{[#");
|
||||
bool hasPluralTypes = text.Contains("[i2p_");
|
||||
if (!HasParameters(text) || !hasPluralParams && !hasPluralTypes)
|
||||
{
|
||||
return GetTranslation (text, LanguageCodeTo, dict);
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
string pluralTranslation = null;
|
||||
bool forcePluralParam = hasPluralParams;
|
||||
|
||||
|
||||
for (var i = ePluralType.Plural; i >= 0; --i)
|
||||
{
|
||||
var pluralType = i.ToString();
|
||||
if (!GoogleLanguages.LanguageHasPluralType(LanguageCodeTo, pluralType))
|
||||
continue;
|
||||
|
||||
var newText = GetPluralText(text, pluralType);
|
||||
int testNumber = GoogleLanguages.GetPluralTestNumber(LanguageCodeTo, i);
|
||||
|
||||
var parameter = GetPluralParameter(newText, forcePluralParam);
|
||||
if (!string.IsNullOrEmpty(parameter))
|
||||
newText = newText.Replace(parameter, testNumber.ToString());
|
||||
|
||||
var translation = GetTranslation(newText, LanguageCodeTo, dict);
|
||||
//Debug.LogFormat("from: {0} -> {1}", newText, translation);
|
||||
if (!string.IsNullOrEmpty(parameter))
|
||||
translation = translation.Replace(testNumber.ToString(), parameter);
|
||||
|
||||
if (i==ePluralType.Plural)
|
||||
{
|
||||
pluralTranslation = translation;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (translation == pluralTranslation)
|
||||
continue;
|
||||
sb.AppendFormat("[i2p_{0}]", pluralType);
|
||||
}
|
||||
sb.Append(translation);
|
||||
}
|
||||
|
||||
return sb.ToString ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static string UppercaseFirst(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
char[] a = s.ToLower().ToCharArray();
|
||||
a[0] = char.ToUpper(a[0]);
|
||||
return new string(a);
|
||||
}
|
||||
public static string TitleCase(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
#if NETFX_CORE
|
||||
var sb = new StringBuilder(s);
|
||||
sb[0] = char.ToUpper(sb[0]);
|
||||
for (int i = 1, imax=s.Length; i<imax; ++i)
|
||||
{
|
||||
if (char.IsWhiteSpace(sb[i - 1]))
|
||||
sb[i] = char.ToUpper(sb[i]);
|
||||
else
|
||||
sb[i] = char.ToLower(sb[i]);
|
||||
}
|
||||
return sb.ToString();
|
||||
#else
|
||||
return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 206e4bf72a490864e9bcb59edbdddaed
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6bd173cd8524b04daa3dabce666b456
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace TEngine.Localization
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
|
||||
public class TranslationJob : IDisposable
|
||||
{
|
||||
public eJobState mJobState = eJobState.Running;
|
||||
|
||||
public enum eJobState { Running, Succeeded, Failed }
|
||||
|
||||
public virtual eJobState GetState() { return mJobState; }
|
||||
|
||||
public virtual void Dispose() { }
|
||||
|
||||
}
|
||||
|
||||
public class TranslationJob_WWW : TranslationJob
|
||||
{
|
||||
public UnityWebRequest www;
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (www!=null)
|
||||
www.Dispose();
|
||||
www = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7dae211a5bb44db46a568fb70fca3296
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user