1[
WorkbenchPluginAttribute(name: PLUGIN_NAME, description:
"Find non-localized text in UI", wbModules: {
"LocalizationEditor" }, shortcut:
"Ctrl+Shift+A")]
4 [
Attribute(defvalue:
"0",
desc:
"Add non-localized texts to the currently opened file")]
7 [
Attribute(defvalue:
"",
desc:
"To which field must the non-localized text be set - e.g m_sSource, Target_en_us, etc")]
10 [
Attribute(defvalue:
"ENF-",
desc:
"Id field prefix for auto-generated ids")]
13 protected static const string PLUGIN_NAME =
"Check localization in UI";
19 protected static const string ID_WHITELIST =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";
23 override event void Run()
28 LocalizationEditor localizationEditor = Workbench.GetModule(LocalizationEditor);
29 if (!localizationEditor)
34 Workbench.Dialog(
PLUGIN_NAME,
"The Source Field is empty - please provide it if you intend to add it to the localization file");
39 array<ResourceName> resourceNames = {};
41 filter.fileExtensions = {
"layout" };
44 int count = resourceNames.Count();
47 if (Workbench.ScriptDialog(
49 "You are about to scan " + count +
" layout files. Continue?",
50 new WorkbenchDialog_OKCancel()) == 0)
56 int reportsCount = reports.Count();
59 Workbench.Dialog(
PLUGIN_NAME,
"All texts in UI are localized.");
63 array<string> translationsToAdd;
65 translationsToAdd = {};
69 foreach (
int i, CheckLocalizationPluginReport report : reports)
72 reportText += report.m_sResourceName;
74 reportText +=
"\n\n" + report.m_sResourceName;
78 reportText +=
string.Format(
"\n \"%2\" at %1", reportEntry.m_sPath, reportEntry.m_sText);
80 translationsToAdd.Insert(reportEntry.m_sText);
86 Workbench.Dialog(
PLUGIN_NAME,
string.Format(
"Found %1 layouts with %2 non-localized texts!", reportsCount, missingCount), reportText);
90 if (!localizationEditor.GetTable())
93 string message =
"You are about to add the following " + missingCount +
" non-localized texts to the translation table.";
94 foreach (
int i,
string translationToAdd : translationsToAdd)
103 translationToAdd.Replace(
"\n",
"\\n");
104 int length = translationToAdd.Length();
108 message +=
"\n- " + translationToAdd;
111 message +=
"\n\nContinue?";
113 if (Workbench.ScriptDialog(
PLUGIN_NAME, message,
new WorkbenchDialog_OKCancel()) == 0)
124 int count = resourceNames.Count();
128 array<ref CheckLocalizationPluginReport> result = {};
130 LocalizationEditor localisationEditor = Workbench.GetModule(LocalizationEditor);
131 float prevProgress, currProgress;
132 WBProgressDialog progress =
new WBProgressDialog(
"Scanning Layouts", localisationEditor);
135 currProgress = (i + 1) / count;
136 if (currProgress - prevProgress >= 0.01)
138 progress.SetProgress(currProgress);
139 prevProgress = currProgress;
143 if (!resource || !resource.IsValid())
151 int entriesCount = reportEntries.Count();
152 if (entriesCount < 1)
155 CheckLocalizationPluginReport report =
new CheckLocalizationPluginReport();
157 report.m_aEntries = {};
158 report.m_aEntries.Reserve(entriesCount);
161 report.m_aEntries.Insert(reportEntry);
164 result.Insert(report);
177 array<ref CheckLocalizationPluginReportEntry> result = {};
178 string widgetName = widgetSource.GetName();
179 if (widgetName.IsEmpty())
182 widgetName =
string.Format(
"%1[%2]", widgetSource.GetClassName(),
index);
184 widgetName =
string.Format(
"%1[?]", widgetSource.GetClassName());
188 if (widgetName.Contains(
"/"))
198 if (widgetSource.Get(
"Text", text) && !text.IsEmpty() && !text.Contains(
"#"))
201 report.m_sPath =
path;
202 report.m_sText = text;
203 result.Insert(report);
206 for (
int i, count = widgetSource.GetNumChildren(); i < count; i++)
215 result.Insert(reportEntry);
227 if (sourceTexts.IsEmpty())
232 array<string> existingIDs = {};
233 for (
int i, itemsCount = items.Count(); i < itemsCount; ++i)
237 existingIDs.Insert(
id);
241 int sourceIndex = -1;
242 foreach (
string sourceText : sourceTexts)
245 bool hasID = existingIDs.Contains(
id);
248 for (
int i; i < 1000; ++i)
251 hasID = existingIDs.Contains(
id);
263 BaseContainer item = localizationEditor.InsertItem(
id,
true,
true);
269 localizationEditor.DeleteItem(
id);
275 localizationEditor.ModifyProperty(item, sourceIndex, sourceText);
278 localizationEditor.EndModify();
285 protected string GetTextId(
string text,
int attemptNumber = -1)
287 bool afterSpace =
true;
288 string filteredAndCased;
289 for (
int i, length = text.Length(); i < length; ++i)
291 string character = text[i];
292 if (character ==
" " || character ==
"\t" || character ==
"\n")
305 filteredAndCased += character;
309 if (filteredAndCased.IsEmpty())
311 if (attemptNumber < 0)
314 return m_sIdPrefix +
"Rename_" + attemptNumber.ToString(3);
318 if (attemptNumber < 0)
321 return m_sIdPrefix + filteredAndCased + attemptNumber.ToString(3);
328 Workbench.ScriptDialog(
PLUGIN_NAME,
string.Empty,
this);
339class CheckLocalizationPluginReport
342 ref array<ref CheckLocalizationPluginReportEntry> m_aEntries;
ResourceName resourceName
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
ResourceName m_sResourceName
class WorkbenchDialog_AbortRetryIgnore ButtonAttribute("OK", true)
static const string PLUGIN_NAME
override event void Run()
static const int MAX_DISPLAYED_TEXT_LENGTH
cuts the translation line at 50 chars (45 + ellipsis)
static const int ID_MAX_LENGTH
array< ref CheckLocalizationPluginReport > GetNonLocalizedReports(notnull array< ResourceName > resourceNames)
array< ref CheckLocalizationPluginReportEntry > GetNonLocalizedReportEntries(notnull WidgetSource widgetSource, string path=string.Empty, int index=-1)
static const string ID_FIELD
void AddTranslationsToTable(notnull LocalizationEditor localizationEditor, notnull array< string > sourceTexts)
string GetTextId(string text, int attemptNumber=-1)
static const string ID_WHITELIST
static const int MAX_DISPLAYED_TEXTS
max item ids displayed in the "are you sure?" modal
static const int LAYOUT_WARNING_THRESHOLD
rings at 100 and above
bool m_bAddToLocalizationFile
Object holding reference to resource. In destructor release the resource.
Object used for holding filtering params for ResourceDatabase.SearchResources() method.
SCR_FieldOfViewSettings Attribute