LanguageSourceData_Terms.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. using System;
  2. using UnityEngine;
  3. using System.Linq;
  4. using System.Collections.Generic;
  5. using Object = UnityEngine.Object;
  6. namespace I2.Loc
  7. {
  8. public partial class LanguageSourceData
  9. {
  10. #region Language
  11. public void UpdateDictionary(bool force = false)
  12. {
  13. if (!force && mDictionary != null && mDictionary.Count == mTerms.Count)
  14. return;
  15. StringComparer comparer = (CaseInsensitiveTerms ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal);
  16. if (mDictionary.Comparer != comparer)
  17. mDictionary = new Dictionary<string, TermData>(comparer);
  18. else
  19. mDictionary.Clear();
  20. for (int i = 0, imax = mTerms.Count; i < imax; ++i)
  21. {
  22. var termData = mTerms[i];
  23. ValidateFullTerm(ref termData.Term);
  24. mDictionary[termData.Term]= mTerms[i];
  25. mTerms[i].Validate();
  26. }
  27. if (I2Utils.IsPlaying())
  28. {
  29. SaveLanguages(true);
  30. }
  31. }
  32. public string GetTranslation (string term, string overrideLanguage = null, string overrideSpecialization = null, bool skipDisabled = false, bool allowCategoryMistmatch = false)
  33. {
  34. string Translation;
  35. if (TryGetTranslation(term, out Translation, overrideLanguage:overrideLanguage, overrideSpecialization:overrideSpecialization, skipDisabled:skipDisabled, allowCategoryMistmatch:allowCategoryMistmatch))
  36. return Translation;
  37. return string.Empty;
  38. }
  39. public bool TryGetTranslation (string term, out string Translation, string overrideLanguage=null, string overrideSpecialization=null, bool skipDisabled=false, bool allowCategoryMistmatch=false)
  40. {
  41. int Index = GetLanguageIndex( overrideLanguage==null ? LocalizationManager.CurrentLanguage : overrideLanguage, SkipDisabled: false );
  42. if (Index>=0 && (!skipDisabled || mLanguages[Index].IsEnabled()))
  43. {
  44. TermData data = GetTermData(term, allowCategoryMistmatch:allowCategoryMistmatch);
  45. if (data!=null)
  46. {
  47. Translation = data.GetTranslation(Index, overrideSpecialization, editMode:true);
  48. // "---" is a code to define that the translation is meant to be empty
  49. if (Translation == "---")
  50. {
  51. Translation = string.Empty;
  52. return true;
  53. }
  54. else
  55. if (!string.IsNullOrEmpty(Translation))
  56. {
  57. // has a valid translation
  58. return true;
  59. }
  60. else
  61. Translation = null;
  62. }
  63. if (OnMissingTranslation == MissingTranslationAction.ShowWarning)
  64. {
  65. Translation = string.Format("<!-Missing Translation [{0}]-!>", term);
  66. return true;
  67. }
  68. else
  69. if (OnMissingTranslation == MissingTranslationAction.Fallback && data!=null)
  70. {
  71. return TryGetFallbackTranslation(data, out Translation, Index, overrideSpecialization, skipDisabled);
  72. }
  73. else
  74. if (OnMissingTranslation == MissingTranslationAction.Empty)
  75. {
  76. Translation = string.Empty;
  77. return true;
  78. }
  79. else
  80. if (OnMissingTranslation == MissingTranslationAction.ShowTerm)
  81. {
  82. Translation = term;
  83. return true;
  84. }
  85. }
  86. Translation = null;
  87. return false;
  88. }
  89. bool TryGetFallbackTranslation(TermData termData, out string Translation, int langIndex, string overrideSpecialization = null, bool skipDisabled = false)
  90. {
  91. // Find base Language Code
  92. string baseLanguage = mLanguages[langIndex].Code;
  93. if (!string.IsNullOrEmpty(baseLanguage))
  94. {
  95. if (baseLanguage.Contains('-'))
  96. {
  97. baseLanguage = baseLanguage.Substring(0, baseLanguage.IndexOf('-'));
  98. }
  99. // Try finding in any of the Region of the base language
  100. for (int i = 0; i < mLanguages.Count; ++i)
  101. {
  102. if (i != langIndex &&
  103. mLanguages[i].Code.StartsWith(baseLanguage) &&
  104. (!skipDisabled || mLanguages[i].IsEnabled()) )
  105. {
  106. Translation = termData.GetTranslation(i, overrideSpecialization, editMode: true);
  107. if (!string.IsNullOrEmpty(Translation))
  108. return true;
  109. }
  110. }
  111. }
  112. // Otherwise, Try finding the first active language with a valid translation
  113. for (int i = 0; i < mLanguages.Count; ++i)
  114. {
  115. if (i!=langIndex &&
  116. (!skipDisabled || mLanguages[i].IsEnabled()) &&
  117. (baseLanguage==null || !mLanguages[i].Code.StartsWith(baseLanguage)))
  118. {
  119. Translation = termData.GetTranslation(i, overrideSpecialization, editMode: true);
  120. if (!string.IsNullOrEmpty(Translation))
  121. return true;
  122. }
  123. }
  124. Translation = null;
  125. return false;
  126. }
  127. public TermData AddTerm( string term )
  128. {
  129. return AddTerm (term, eTermType.Text);
  130. }
  131. public TermData GetTermData( string term, bool allowCategoryMistmatch = false)
  132. {
  133. if (string.IsNullOrEmpty(term))
  134. return null;
  135. if (mDictionary.Count==0)// != mTerms.Count)
  136. UpdateDictionary();
  137. TermData data;
  138. if (mDictionary.TryGetValue(term, out data))
  139. return data;
  140. TermData d = null;
  141. if (allowCategoryMistmatch)
  142. {
  143. var keyPart = GetKeyFromFullTerm (term);
  144. foreach (var kvp in mDictionary)
  145. if (kvp.Value.IsTerm (keyPart, true))
  146. {
  147. if (d == null)
  148. d = kvp.Value;
  149. else
  150. return null;
  151. }
  152. }
  153. return d;
  154. }
  155. public bool ContainsTerm(string term)
  156. {
  157. return (GetTermData(term)!=null);
  158. }
  159. public List<string> GetTermsList ( string Category = null )
  160. {
  161. if (mDictionary.Count != mTerms.Count)
  162. UpdateDictionary();
  163. if (string.IsNullOrEmpty( Category ))
  164. return new List<string>( mDictionary.Keys );
  165. else
  166. {
  167. var terms = new List<string>();
  168. for (int i=0; i<mTerms.Count; ++i)
  169. {
  170. var term = mTerms[i];
  171. if (GetCategoryFromFullTerm( term.Term ) == Category)
  172. terms.Add( term.Term );
  173. }
  174. return terms;
  175. }
  176. }
  177. public TermData AddTerm( string NewTerm, eTermType termType, bool SaveSource = true )
  178. {
  179. ValidateFullTerm( ref NewTerm );
  180. NewTerm = NewTerm.Trim ();
  181. if (mLanguages.Count == 0)
  182. AddLanguage ("English", "en");
  183. // Don't duplicate Terms
  184. TermData data = GetTermData(NewTerm);
  185. if (data==null)
  186. {
  187. data = new TermData();
  188. data.Term = NewTerm;
  189. data.TermType = termType;
  190. data.Languages = new string[ mLanguages.Count ];
  191. data.Flags = new byte[ mLanguages.Count ];
  192. mTerms.Add (data);
  193. mDictionary.Add ( NewTerm, data);
  194. #if UNITY_EDITOR
  195. if (SaveSource)
  196. {
  197. Editor_SetDirty();
  198. UnityEditor.AssetDatabase.SaveAssets();
  199. }
  200. #endif
  201. }
  202. return data;
  203. }
  204. public void RemoveTerm( string term )
  205. {
  206. for (int i=0, imax=mTerms.Count; i<imax; ++i)
  207. if (mTerms[i].Term==term)
  208. {
  209. mTerms.RemoveAt(i);
  210. mDictionary.Remove(term);
  211. return;
  212. }
  213. }
  214. public static void ValidateFullTerm( ref string Term )
  215. {
  216. Term = Term.Replace('\\', '/');
  217. Term = Term.Trim();
  218. if (Term.StartsWith(EmptyCategory, StringComparison.Ordinal))
  219. {
  220. if (Term.Length>EmptyCategory.Length && Term[EmptyCategory.Length]=='/')
  221. Term = Term.Substring(EmptyCategory.Length+1);
  222. }
  223. Term = I2Utils.GetValidTermName(Term, true);
  224. }
  225. #endregion
  226. }
  227. }