editor_locale_dialog.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. /**************************************************************************/
  2. /* editor_locale_dialog.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #include "editor_locale_dialog.h"
  31. #include "core/config/project_settings.h"
  32. #include "core/string/translation_server.h"
  33. #include "editor/editor_undo_redo_manager.h"
  34. #include "editor/themes/editor_scale.h"
  35. #include "scene/gui/check_button.h"
  36. #include "scene/gui/line_edit.h"
  37. #include "scene/gui/option_button.h"
  38. #include "scene/gui/tree.h"
  39. void EditorLocaleDialog::_notification(int p_what) {
  40. if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {
  41. // TRANSLATORS: This is the label for a list of writing systems.
  42. script_label1->set_text(TTR("Script:", "Locale"));
  43. // TRANSLATORS: This refers to a writing system.
  44. script_label2->set_text(TTR("Script", "Locale"));
  45. script_list->set_accessibility_name(TTR("Script", "Locale"));
  46. script_code->set_accessibility_name(TTR("Script", "Locale"));
  47. }
  48. }
  49. void EditorLocaleDialog::_bind_methods() {
  50. ADD_SIGNAL(MethodInfo("locale_selected", PropertyInfo(Variant::STRING, "locale")));
  51. }
  52. void EditorLocaleDialog::ok_pressed() {
  53. if (edit_filters->is_pressed()) {
  54. return; // Do not update, if in filter edit mode.
  55. }
  56. String locale;
  57. if (lang_code->get_text().is_empty()) {
  58. return; // Language code is required.
  59. }
  60. locale = lang_code->get_text();
  61. if (!script_code->get_text().is_empty()) {
  62. locale += "_" + script_code->get_text();
  63. }
  64. if (!country_code->get_text().is_empty()) {
  65. locale += "_" + country_code->get_text();
  66. }
  67. if (!variant_code->get_text().is_empty()) {
  68. locale += "_" + variant_code->get_text();
  69. }
  70. emit_signal(SNAME("locale_selected"), TranslationServer::get_singleton()->standardize_locale(locale));
  71. hide();
  72. }
  73. void EditorLocaleDialog::_item_selected() {
  74. if (updating_lists) {
  75. return;
  76. }
  77. if (edit_filters->is_pressed()) {
  78. return; // Do not update, if in filter edit mode.
  79. }
  80. TreeItem *l = lang_list->get_selected();
  81. if (l) {
  82. lang_code->set_text(l->get_metadata(0).operator String());
  83. }
  84. TreeItem *s = script_list->get_selected();
  85. if (s) {
  86. script_code->set_text(s->get_metadata(0).operator String());
  87. }
  88. TreeItem *c = cnt_list->get_selected();
  89. if (c) {
  90. country_code->set_text(c->get_metadata(0).operator String());
  91. }
  92. }
  93. void EditorLocaleDialog::_toggle_advanced(bool p_checked) {
  94. if (!p_checked) {
  95. script_code->set_text("");
  96. variant_code->set_text("");
  97. }
  98. _update_tree();
  99. }
  100. void EditorLocaleDialog::_post_popup() {
  101. ConfirmationDialog::_post_popup();
  102. if (!locale_set) {
  103. lang_code->set_text("");
  104. script_code->set_text("");
  105. country_code->set_text("");
  106. variant_code->set_text("");
  107. }
  108. edit_filters->set_pressed(false);
  109. _update_tree();
  110. }
  111. void EditorLocaleDialog::_filter_lang_option_changed() {
  112. TreeItem *t = lang_list->get_edited();
  113. String lang = t->get_metadata(0);
  114. bool checked = t->is_checked(0);
  115. Variant prev;
  116. Array f_lang_all;
  117. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/language_filter")) {
  118. f_lang_all = GLOBAL_GET("internationalization/locale/language_filter");
  119. prev = f_lang_all;
  120. }
  121. int l_idx = f_lang_all.find(lang);
  122. if (checked) {
  123. if (l_idx == -1) {
  124. f_lang_all.append(lang);
  125. }
  126. } else {
  127. if (l_idx != -1) {
  128. f_lang_all.remove_at(l_idx);
  129. }
  130. }
  131. f_lang_all.sort();
  132. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  133. undo_redo->create_action(TTR("Changed Locale Language Filter"));
  134. undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/language_filter", f_lang_all);
  135. undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/language_filter", prev);
  136. undo_redo->commit_action();
  137. }
  138. void EditorLocaleDialog::_filter_script_option_changed() {
  139. TreeItem *t = script_list->get_edited();
  140. String scr_code = t->get_metadata(0);
  141. bool checked = t->is_checked(0);
  142. Variant prev;
  143. Array f_script_all;
  144. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/script_filter")) {
  145. f_script_all = GLOBAL_GET("internationalization/locale/script_filter");
  146. prev = f_script_all;
  147. }
  148. int l_idx = f_script_all.find(scr_code);
  149. if (checked) {
  150. if (l_idx == -1) {
  151. f_script_all.append(scr_code);
  152. }
  153. } else {
  154. if (l_idx != -1) {
  155. f_script_all.remove_at(l_idx);
  156. }
  157. }
  158. f_script_all.sort();
  159. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  160. undo_redo->create_action(TTR("Changed Locale Script Filter"));
  161. undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/script_filter", f_script_all);
  162. undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/script_filter", prev);
  163. undo_redo->commit_action();
  164. }
  165. void EditorLocaleDialog::_filter_cnt_option_changed() {
  166. TreeItem *t = cnt_list->get_edited();
  167. String cnt = t->get_metadata(0);
  168. bool checked = t->is_checked(0);
  169. Variant prev;
  170. Array f_cnt_all;
  171. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/country_filter")) {
  172. f_cnt_all = GLOBAL_GET("internationalization/locale/country_filter");
  173. prev = f_cnt_all;
  174. }
  175. int l_idx = f_cnt_all.find(cnt);
  176. if (checked) {
  177. if (l_idx == -1) {
  178. f_cnt_all.append(cnt);
  179. }
  180. } else {
  181. if (l_idx != -1) {
  182. f_cnt_all.remove_at(l_idx);
  183. }
  184. }
  185. f_cnt_all.sort();
  186. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  187. undo_redo->create_action(TTR("Changed Locale Country Filter"));
  188. undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/country_filter", f_cnt_all);
  189. undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/country_filter", prev);
  190. undo_redo->commit_action();
  191. }
  192. void EditorLocaleDialog::_filter_mode_changed(int p_mode) {
  193. int f_mode = filter_mode->get_selected_id();
  194. Variant prev;
  195. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter_mode")) {
  196. prev = GLOBAL_GET("internationalization/locale/locale_filter_mode");
  197. }
  198. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  199. undo_redo->create_action(TTR("Changed Locale Filter Mode"));
  200. undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter_mode", f_mode);
  201. undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter_mode", prev);
  202. undo_redo->commit_action();
  203. _update_tree();
  204. }
  205. void EditorLocaleDialog::_edit_filters(bool p_checked) {
  206. _update_tree();
  207. }
  208. void EditorLocaleDialog::_update_tree() {
  209. updating_lists = true;
  210. int filter = SHOW_ALL_LOCALES;
  211. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter_mode")) {
  212. filter = GLOBAL_GET_CACHED(int, "internationalization/locale/locale_filter_mode");
  213. }
  214. Array f_lang_all;
  215. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/language_filter")) {
  216. f_lang_all = GLOBAL_GET("internationalization/locale/language_filter");
  217. }
  218. Array f_cnt_all;
  219. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/country_filter")) {
  220. f_cnt_all = GLOBAL_GET("internationalization/locale/country_filter");
  221. }
  222. Array f_script_all;
  223. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/script_filter")) {
  224. f_script_all = GLOBAL_GET("internationalization/locale/script_filter");
  225. }
  226. bool is_edit_mode = edit_filters->is_pressed();
  227. filter_mode->select(filter);
  228. // Hide text advanced edit and disable OK button if in filter edit mode.
  229. advanced->set_visible(!is_edit_mode);
  230. hb_locale->set_visible(!is_edit_mode && advanced->is_pressed());
  231. vb_script_list->set_visible(advanced->is_pressed());
  232. get_ok_button()->set_disabled(is_edit_mode);
  233. // Update language list.
  234. lang_list->clear();
  235. TreeItem *l_root = lang_list->create_item(nullptr);
  236. lang_list->set_hide_root(true);
  237. Vector<String> languages = TranslationServer::get_singleton()->get_all_languages();
  238. for (const String &E : languages) {
  239. if (is_edit_mode || (filter == SHOW_ALL_LOCALES) || f_lang_all.has(E) || f_lang_all.is_empty()) {
  240. const String &lang = TranslationServer::get_singleton()->get_language_name(E);
  241. TreeItem *t = lang_list->create_item(l_root);
  242. if (is_edit_mode) {
  243. t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
  244. t->set_editable(0, true);
  245. t->set_checked(0, f_lang_all.has(E));
  246. } else if (lang_code->get_text() == E) {
  247. t->select(0);
  248. }
  249. t->set_text(0, vformat("%s [%s]", lang, E));
  250. t->set_metadata(0, E);
  251. }
  252. }
  253. // Update script list.
  254. script_list->clear();
  255. TreeItem *s_root = script_list->create_item(nullptr);
  256. script_list->set_hide_root(true);
  257. if (!is_edit_mode) {
  258. TreeItem *t = script_list->create_item(s_root);
  259. t->set_text(0, TTRC("[Default]"));
  260. t->set_metadata(0, "");
  261. }
  262. Vector<String> scripts = TranslationServer::get_singleton()->get_all_scripts();
  263. for (const String &E : scripts) {
  264. if (is_edit_mode || (filter == SHOW_ALL_LOCALES) || f_script_all.has(E) || f_script_all.is_empty()) {
  265. const String &scr_code = TranslationServer::get_singleton()->get_script_name(E);
  266. TreeItem *t = script_list->create_item(s_root);
  267. if (is_edit_mode) {
  268. t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
  269. t->set_editable(0, true);
  270. t->set_checked(0, f_script_all.has(E));
  271. } else if (script_code->get_text() == E) {
  272. t->select(0);
  273. }
  274. t->set_text(0, vformat("%s [%s]", scr_code, E));
  275. t->set_metadata(0, E);
  276. }
  277. }
  278. // Update country list.
  279. cnt_list->clear();
  280. TreeItem *c_root = cnt_list->create_item(nullptr);
  281. cnt_list->set_hide_root(true);
  282. if (!is_edit_mode) {
  283. TreeItem *t = cnt_list->create_item(c_root);
  284. t->set_text(0, TTRC("[Default]"));
  285. t->set_metadata(0, "");
  286. }
  287. Vector<String> countries = TranslationServer::get_singleton()->get_all_countries();
  288. for (const String &E : countries) {
  289. if (is_edit_mode || (filter == SHOW_ALL_LOCALES) || f_cnt_all.has(E) || f_cnt_all.is_empty()) {
  290. const String &cnt = TranslationServer::get_singleton()->get_country_name(E);
  291. TreeItem *t = cnt_list->create_item(c_root);
  292. if (is_edit_mode) {
  293. t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
  294. t->set_editable(0, true);
  295. t->set_checked(0, f_cnt_all.has(E));
  296. } else if (country_code->get_text() == E) {
  297. t->select(0);
  298. }
  299. t->set_text(0, vformat("%s [%s]", cnt, E));
  300. t->set_metadata(0, E);
  301. }
  302. }
  303. updating_lists = false;
  304. }
  305. void EditorLocaleDialog::set_locale(const String &p_locale) {
  306. const String &locale = TranslationServer::get_singleton()->standardize_locale(p_locale);
  307. if (locale.is_empty()) {
  308. locale_set = false;
  309. lang_code->set_text("");
  310. script_code->set_text("");
  311. country_code->set_text("");
  312. variant_code->set_text("");
  313. } else {
  314. locale_set = true;
  315. Vector<String> locale_elements = p_locale.split("_");
  316. lang_code->set_text(locale_elements[0]);
  317. if (locale_elements.size() >= 2) {
  318. if (locale_elements[1].length() == 4 && is_ascii_upper_case(locale_elements[1][0]) && is_ascii_lower_case(locale_elements[1][1]) && is_ascii_lower_case(locale_elements[1][2]) && is_ascii_lower_case(locale_elements[1][3])) {
  319. script_code->set_text(locale_elements[1]);
  320. advanced->set_pressed(true);
  321. }
  322. if (locale_elements[1].length() == 2 && is_ascii_upper_case(locale_elements[1][0]) && is_ascii_upper_case(locale_elements[1][1])) {
  323. country_code->set_text(locale_elements[1]);
  324. }
  325. }
  326. if (locale_elements.size() >= 3) {
  327. if (locale_elements[2].length() == 2 && is_ascii_upper_case(locale_elements[2][0]) && is_ascii_upper_case(locale_elements[2][1])) {
  328. country_code->set_text(locale_elements[2]);
  329. } else {
  330. variant_code->set_text(locale_elements[2].to_lower());
  331. advanced->set_pressed(true);
  332. }
  333. }
  334. if (locale_elements.size() >= 4) {
  335. variant_code->set_text(locale_elements[3].to_lower());
  336. advanced->set_pressed(true);
  337. }
  338. }
  339. }
  340. void EditorLocaleDialog::popup_locale_dialog() {
  341. popup_centered_clamped(Size2(1050, 700) * EDSCALE, 0.8);
  342. }
  343. EditorLocaleDialog::EditorLocaleDialog() {
  344. set_title(TTRC("Select a Locale"));
  345. VBoxContainer *vb = memnew(VBoxContainer);
  346. {
  347. HBoxContainer *hb_filter = memnew(HBoxContainer);
  348. {
  349. filter_mode = memnew(OptionButton);
  350. filter_mode->set_accessibility_name(TTRC("Locale Filter"));
  351. filter_mode->add_item(TTRC("Show All Locales"), SHOW_ALL_LOCALES);
  352. filter_mode->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  353. filter_mode->add_item(TTRC("Show Selected Locales Only"), SHOW_ONLY_SELECTED_LOCALES);
  354. filter_mode->select(0);
  355. filter_mode->connect(SceneStringName(item_selected), callable_mp(this, &EditorLocaleDialog::_filter_mode_changed));
  356. hb_filter->add_child(filter_mode);
  357. }
  358. {
  359. edit_filters = memnew(CheckButton);
  360. edit_filters->set_text(TTRC("Edit Filters"));
  361. edit_filters->set_toggle_mode(true);
  362. edit_filters->set_pressed(false);
  363. edit_filters->connect(SceneStringName(toggled), callable_mp(this, &EditorLocaleDialog::_edit_filters));
  364. hb_filter->add_child(edit_filters);
  365. }
  366. {
  367. advanced = memnew(CheckButton);
  368. advanced->set_text(TTRC("Advanced"));
  369. advanced->set_toggle_mode(true);
  370. advanced->set_pressed(false);
  371. advanced->connect(SceneStringName(toggled), callable_mp(this, &EditorLocaleDialog::_toggle_advanced));
  372. hb_filter->add_child(advanced);
  373. }
  374. vb->add_child(hb_filter);
  375. }
  376. {
  377. HBoxContainer *hb_lists = memnew(HBoxContainer);
  378. hb_lists->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  379. {
  380. VBoxContainer *vb_lang_list = memnew(VBoxContainer);
  381. vb_lang_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  382. {
  383. Label *lang_lbl = memnew(Label);
  384. lang_lbl->set_text(TTRC("Language:"));
  385. vb_lang_list->add_child(lang_lbl);
  386. }
  387. {
  388. lang_list = memnew(Tree);
  389. lang_list->set_accessibility_name(TTRC("Language"));
  390. lang_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
  391. lang_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  392. lang_list->connect("cell_selected", callable_mp(this, &EditorLocaleDialog::_item_selected));
  393. lang_list->set_columns(1);
  394. lang_list->connect("item_edited", callable_mp(this, &EditorLocaleDialog::_filter_lang_option_changed));
  395. vb_lang_list->add_child(lang_list);
  396. }
  397. hb_lists->add_child(vb_lang_list);
  398. }
  399. {
  400. vb_script_list = memnew(VBoxContainer);
  401. vb_script_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  402. {
  403. script_label1 = memnew(Label);
  404. script_label1->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
  405. vb_script_list->add_child(script_label1);
  406. }
  407. {
  408. script_list = memnew(Tree);
  409. script_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
  410. script_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  411. script_list->connect("cell_selected", callable_mp(this, &EditorLocaleDialog::_item_selected));
  412. script_list->set_columns(1);
  413. script_list->connect("item_edited", callable_mp(this, &EditorLocaleDialog::_filter_script_option_changed));
  414. vb_script_list->add_child(script_list);
  415. }
  416. hb_lists->add_child(vb_script_list);
  417. }
  418. {
  419. VBoxContainer *vb_cnt_list = memnew(VBoxContainer);
  420. vb_cnt_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  421. {
  422. Label *cnt_lbl = memnew(Label);
  423. cnt_lbl->set_text(TTRC("Country:"));
  424. vb_cnt_list->add_child(cnt_lbl);
  425. }
  426. {
  427. cnt_list = memnew(Tree);
  428. cnt_list->set_accessibility_name(TTRC("Country"));
  429. cnt_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
  430. cnt_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  431. cnt_list->connect("cell_selected", callable_mp(this, &EditorLocaleDialog::_item_selected));
  432. cnt_list->set_columns(1);
  433. cnt_list->connect("item_edited", callable_mp(this, &EditorLocaleDialog::_filter_cnt_option_changed));
  434. vb_cnt_list->add_child(cnt_list);
  435. }
  436. hb_lists->add_child(vb_cnt_list);
  437. }
  438. vb->add_child(hb_lists);
  439. }
  440. {
  441. hb_locale = memnew(HBoxContainer);
  442. hb_locale->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  443. {
  444. {
  445. VBoxContainer *vb_language = memnew(VBoxContainer);
  446. vb_language->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  447. {
  448. Label *language_lbl = memnew(Label);
  449. language_lbl->set_text(TTRC("Language"));
  450. vb_language->add_child(language_lbl);
  451. }
  452. {
  453. lang_code = memnew(LineEdit);
  454. lang_code->set_max_length(3);
  455. lang_code->set_accessibility_name("Language");
  456. vb_language->add_child(lang_code);
  457. }
  458. hb_locale->add_child(vb_language);
  459. }
  460. {
  461. VBoxContainer *vb_script = memnew(VBoxContainer);
  462. vb_script->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  463. {
  464. script_label2 = memnew(Label);
  465. script_label2->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
  466. vb_script->add_child(script_label2);
  467. }
  468. {
  469. script_code = memnew(LineEdit);
  470. script_code->set_max_length(4);
  471. vb_script->add_child(script_code);
  472. }
  473. hb_locale->add_child(vb_script);
  474. }
  475. {
  476. VBoxContainer *vb_country = memnew(VBoxContainer);
  477. vb_country->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  478. {
  479. Label *country_lbl = memnew(Label);
  480. country_lbl->set_text(TTRC("Country"));
  481. vb_country->add_child(country_lbl);
  482. }
  483. {
  484. country_code = memnew(LineEdit);
  485. country_code->set_max_length(2);
  486. country_code->set_tooltip_text("Country");
  487. vb_country->add_child(country_code);
  488. }
  489. hb_locale->add_child(vb_country);
  490. }
  491. {
  492. VBoxContainer *vb_variant = memnew(VBoxContainer);
  493. vb_variant->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  494. {
  495. Label *variant_lbl = memnew(Label);
  496. variant_lbl->set_text(TTRC("Variant"));
  497. vb_variant->add_child(variant_lbl);
  498. }
  499. {
  500. variant_code = memnew(LineEdit);
  501. variant_code->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  502. variant_code->set_placeholder("Variant");
  503. variant_code->set_accessibility_name("Variant");
  504. vb_variant->add_child(variant_code);
  505. }
  506. hb_locale->add_child(vb_variant);
  507. }
  508. }
  509. vb->add_child(hb_locale);
  510. }
  511. add_child(vb);
  512. _update_tree();
  513. set_ok_button_text(TTRC("Select"));
  514. }