editor_locale_dialog.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  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::_bind_methods() {
  40. ADD_SIGNAL(MethodInfo("locale_selected", PropertyInfo(Variant::STRING, "locale")));
  41. }
  42. void EditorLocaleDialog::ok_pressed() {
  43. if (edit_filters->is_pressed()) {
  44. return; // Do not update, if in filter edit mode.
  45. }
  46. String locale;
  47. if (lang_code->get_text().is_empty()) {
  48. return; // Language code is required.
  49. }
  50. locale = lang_code->get_text();
  51. if (!script_code->get_text().is_empty()) {
  52. locale += "_" + script_code->get_text();
  53. }
  54. if (!country_code->get_text().is_empty()) {
  55. locale += "_" + country_code->get_text();
  56. }
  57. if (!variant_code->get_text().is_empty()) {
  58. locale += "_" + variant_code->get_text();
  59. }
  60. emit_signal(SNAME("locale_selected"), TranslationServer::get_singleton()->standardize_locale(locale));
  61. hide();
  62. }
  63. void EditorLocaleDialog::_item_selected() {
  64. if (updating_lists) {
  65. return;
  66. }
  67. if (edit_filters->is_pressed()) {
  68. return; // Do not update, if in filter edit mode.
  69. }
  70. TreeItem *l = lang_list->get_selected();
  71. if (l) {
  72. lang_code->set_text(l->get_metadata(0).operator String());
  73. }
  74. TreeItem *s = script_list->get_selected();
  75. if (s) {
  76. script_code->set_text(s->get_metadata(0).operator String());
  77. }
  78. TreeItem *c = cnt_list->get_selected();
  79. if (c) {
  80. country_code->set_text(c->get_metadata(0).operator String());
  81. }
  82. }
  83. void EditorLocaleDialog::_toggle_advanced(bool p_checked) {
  84. if (!p_checked) {
  85. script_code->set_text("");
  86. variant_code->set_text("");
  87. }
  88. _update_tree();
  89. }
  90. void EditorLocaleDialog::_post_popup() {
  91. ConfirmationDialog::_post_popup();
  92. if (!locale_set) {
  93. lang_code->set_text("");
  94. script_code->set_text("");
  95. country_code->set_text("");
  96. variant_code->set_text("");
  97. }
  98. edit_filters->set_pressed(false);
  99. _update_tree();
  100. }
  101. void EditorLocaleDialog::_filter_lang_option_changed() {
  102. TreeItem *t = lang_list->get_edited();
  103. String lang = t->get_metadata(0);
  104. bool checked = t->is_checked(0);
  105. Variant prev;
  106. Array f_lang_all;
  107. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/language_filter")) {
  108. f_lang_all = GLOBAL_GET("internationalization/locale/language_filter");
  109. prev = f_lang_all;
  110. }
  111. int l_idx = f_lang_all.find(lang);
  112. if (checked) {
  113. if (l_idx == -1) {
  114. f_lang_all.append(lang);
  115. }
  116. } else {
  117. if (l_idx != -1) {
  118. f_lang_all.remove_at(l_idx);
  119. }
  120. }
  121. f_lang_all.sort();
  122. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  123. undo_redo->create_action(TTR("Changed Locale Language Filter"));
  124. undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/language_filter", f_lang_all);
  125. undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/language_filter", prev);
  126. undo_redo->commit_action();
  127. }
  128. void EditorLocaleDialog::_filter_script_option_changed() {
  129. TreeItem *t = script_list->get_edited();
  130. String scr_code = t->get_metadata(0);
  131. bool checked = t->is_checked(0);
  132. Variant prev;
  133. Array f_script_all;
  134. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/script_filter")) {
  135. f_script_all = GLOBAL_GET("internationalization/locale/script_filter");
  136. prev = f_script_all;
  137. }
  138. int l_idx = f_script_all.find(scr_code);
  139. if (checked) {
  140. if (l_idx == -1) {
  141. f_script_all.append(scr_code);
  142. }
  143. } else {
  144. if (l_idx != -1) {
  145. f_script_all.remove_at(l_idx);
  146. }
  147. }
  148. f_script_all.sort();
  149. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  150. undo_redo->create_action(TTR("Changed Locale Script Filter"));
  151. undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/script_filter", f_script_all);
  152. undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/script_filter", prev);
  153. undo_redo->commit_action();
  154. }
  155. void EditorLocaleDialog::_filter_cnt_option_changed() {
  156. TreeItem *t = cnt_list->get_edited();
  157. String cnt = t->get_metadata(0);
  158. bool checked = t->is_checked(0);
  159. Variant prev;
  160. Array f_cnt_all;
  161. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/country_filter")) {
  162. f_cnt_all = GLOBAL_GET("internationalization/locale/country_filter");
  163. prev = f_cnt_all;
  164. }
  165. int l_idx = f_cnt_all.find(cnt);
  166. if (checked) {
  167. if (l_idx == -1) {
  168. f_cnt_all.append(cnt);
  169. }
  170. } else {
  171. if (l_idx != -1) {
  172. f_cnt_all.remove_at(l_idx);
  173. }
  174. }
  175. f_cnt_all.sort();
  176. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  177. undo_redo->create_action(TTR("Changed Locale Country Filter"));
  178. undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/country_filter", f_cnt_all);
  179. undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/country_filter", prev);
  180. undo_redo->commit_action();
  181. }
  182. void EditorLocaleDialog::_filter_mode_changed(int p_mode) {
  183. int f_mode = filter_mode->get_selected_id();
  184. Variant prev;
  185. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter_mode")) {
  186. prev = GLOBAL_GET("internationalization/locale/locale_filter_mode");
  187. }
  188. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  189. undo_redo->create_action(TTR("Changed Locale Filter Mode"));
  190. undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter_mode", f_mode);
  191. undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter_mode", prev);
  192. undo_redo->commit_action();
  193. _update_tree();
  194. }
  195. void EditorLocaleDialog::_edit_filters(bool p_checked) {
  196. _update_tree();
  197. }
  198. void EditorLocaleDialog::_update_tree() {
  199. updating_lists = true;
  200. int filter = SHOW_ALL_LOCALES;
  201. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter_mode")) {
  202. filter = GLOBAL_GET("internationalization/locale/locale_filter_mode");
  203. }
  204. Array f_lang_all;
  205. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/language_filter")) {
  206. f_lang_all = GLOBAL_GET("internationalization/locale/language_filter");
  207. }
  208. Array f_cnt_all;
  209. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/country_filter")) {
  210. f_cnt_all = GLOBAL_GET("internationalization/locale/country_filter");
  211. }
  212. Array f_script_all;
  213. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/script_filter")) {
  214. f_script_all = GLOBAL_GET("internationalization/locale/script_filter");
  215. }
  216. bool is_edit_mode = edit_filters->is_pressed();
  217. filter_mode->select(filter);
  218. // Hide text advanced edit and disable OK button if in filter edit mode.
  219. advanced->set_visible(!is_edit_mode);
  220. hb_locale->set_visible(!is_edit_mode && advanced->is_pressed());
  221. vb_script_list->set_visible(advanced->is_pressed());
  222. get_ok_button()->set_disabled(is_edit_mode);
  223. // Update language list.
  224. lang_list->clear();
  225. TreeItem *l_root = lang_list->create_item(nullptr);
  226. lang_list->set_hide_root(true);
  227. Vector<String> languages = TranslationServer::get_singleton()->get_all_languages();
  228. for (const String &E : languages) {
  229. if (is_edit_mode || (filter == SHOW_ALL_LOCALES) || f_lang_all.has(E) || f_lang_all.is_empty()) {
  230. const String &lang = TranslationServer::get_singleton()->get_language_name(E);
  231. TreeItem *t = lang_list->create_item(l_root);
  232. if (is_edit_mode) {
  233. t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
  234. t->set_editable(0, true);
  235. t->set_checked(0, f_lang_all.has(E));
  236. } else if (lang_code->get_text() == E) {
  237. t->select(0);
  238. }
  239. t->set_text(0, vformat("%s [%s]", lang, E));
  240. t->set_metadata(0, E);
  241. }
  242. }
  243. // Update script list.
  244. script_list->clear();
  245. TreeItem *s_root = script_list->create_item(nullptr);
  246. script_list->set_hide_root(true);
  247. if (!is_edit_mode) {
  248. TreeItem *t = script_list->create_item(s_root);
  249. t->set_text(0, TTR("[Default]"));
  250. t->set_metadata(0, "");
  251. }
  252. Vector<String> scripts = TranslationServer::get_singleton()->get_all_scripts();
  253. for (const String &E : scripts) {
  254. if (is_edit_mode || (filter == SHOW_ALL_LOCALES) || f_script_all.has(E) || f_script_all.is_empty()) {
  255. const String &scr_code = TranslationServer::get_singleton()->get_script_name(E);
  256. TreeItem *t = script_list->create_item(s_root);
  257. if (is_edit_mode) {
  258. t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
  259. t->set_editable(0, true);
  260. t->set_checked(0, f_script_all.has(E));
  261. } else if (script_code->get_text() == E) {
  262. t->select(0);
  263. }
  264. t->set_text(0, vformat("%s [%s]", scr_code, E));
  265. t->set_metadata(0, E);
  266. }
  267. }
  268. // Update country list.
  269. cnt_list->clear();
  270. TreeItem *c_root = cnt_list->create_item(nullptr);
  271. cnt_list->set_hide_root(true);
  272. if (!is_edit_mode) {
  273. TreeItem *t = cnt_list->create_item(c_root);
  274. t->set_text(0, TTR("[Default]"));
  275. t->set_metadata(0, "");
  276. }
  277. Vector<String> countries = TranslationServer::get_singleton()->get_all_countries();
  278. for (const String &E : countries) {
  279. if (is_edit_mode || (filter == SHOW_ALL_LOCALES) || f_cnt_all.has(E) || f_cnt_all.is_empty()) {
  280. const String &cnt = TranslationServer::get_singleton()->get_country_name(E);
  281. TreeItem *t = cnt_list->create_item(c_root);
  282. if (is_edit_mode) {
  283. t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
  284. t->set_editable(0, true);
  285. t->set_checked(0, f_cnt_all.has(E));
  286. } else if (country_code->get_text() == E) {
  287. t->select(0);
  288. }
  289. t->set_text(0, vformat("%s [%s]", cnt, E));
  290. t->set_metadata(0, E);
  291. }
  292. }
  293. updating_lists = false;
  294. }
  295. void EditorLocaleDialog::set_locale(const String &p_locale) {
  296. const String &locale = TranslationServer::get_singleton()->standardize_locale(p_locale);
  297. if (locale.is_empty()) {
  298. locale_set = false;
  299. lang_code->set_text("");
  300. script_code->set_text("");
  301. country_code->set_text("");
  302. variant_code->set_text("");
  303. } else {
  304. locale_set = true;
  305. Vector<String> locale_elements = p_locale.split("_");
  306. lang_code->set_text(locale_elements[0]);
  307. if (locale_elements.size() >= 2) {
  308. 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])) {
  309. script_code->set_text(locale_elements[1]);
  310. advanced->set_pressed(true);
  311. }
  312. if (locale_elements[1].length() == 2 && is_ascii_upper_case(locale_elements[1][0]) && is_ascii_upper_case(locale_elements[1][1])) {
  313. country_code->set_text(locale_elements[1]);
  314. }
  315. }
  316. if (locale_elements.size() >= 3) {
  317. if (locale_elements[2].length() == 2 && is_ascii_upper_case(locale_elements[2][0]) && is_ascii_upper_case(locale_elements[2][1])) {
  318. country_code->set_text(locale_elements[2]);
  319. } else {
  320. variant_code->set_text(locale_elements[2].to_lower());
  321. advanced->set_pressed(true);
  322. }
  323. }
  324. if (locale_elements.size() >= 4) {
  325. variant_code->set_text(locale_elements[3].to_lower());
  326. advanced->set_pressed(true);
  327. }
  328. }
  329. }
  330. void EditorLocaleDialog::popup_locale_dialog() {
  331. popup_centered_clamped(Size2(1050, 700) * EDSCALE, 0.8);
  332. }
  333. EditorLocaleDialog::EditorLocaleDialog() {
  334. set_title(TTR("Select a Locale"));
  335. VBoxContainer *vb = memnew(VBoxContainer);
  336. {
  337. HBoxContainer *hb_filter = memnew(HBoxContainer);
  338. {
  339. filter_mode = memnew(OptionButton);
  340. filter_mode->add_item(TTR("Show All Locales"), SHOW_ALL_LOCALES);
  341. filter_mode->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  342. filter_mode->add_item(TTR("Show Selected Locales Only"), SHOW_ONLY_SELECTED_LOCALES);
  343. filter_mode->select(0);
  344. filter_mode->connect(SceneStringName(item_selected), callable_mp(this, &EditorLocaleDialog::_filter_mode_changed));
  345. hb_filter->add_child(filter_mode);
  346. }
  347. {
  348. edit_filters = memnew(CheckButton);
  349. edit_filters->set_text(TTR("Edit Filters"));
  350. edit_filters->set_toggle_mode(true);
  351. edit_filters->set_pressed(false);
  352. edit_filters->connect(SceneStringName(toggled), callable_mp(this, &EditorLocaleDialog::_edit_filters));
  353. hb_filter->add_child(edit_filters);
  354. }
  355. {
  356. advanced = memnew(CheckButton);
  357. advanced->set_text(TTR("Advanced"));
  358. advanced->set_toggle_mode(true);
  359. advanced->set_pressed(false);
  360. advanced->connect(SceneStringName(toggled), callable_mp(this, &EditorLocaleDialog::_toggle_advanced));
  361. hb_filter->add_child(advanced);
  362. }
  363. vb->add_child(hb_filter);
  364. }
  365. {
  366. HBoxContainer *hb_lists = memnew(HBoxContainer);
  367. hb_lists->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  368. {
  369. VBoxContainer *vb_lang_list = memnew(VBoxContainer);
  370. vb_lang_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  371. {
  372. Label *lang_lbl = memnew(Label);
  373. lang_lbl->set_text(TTR("Language:"));
  374. vb_lang_list->add_child(lang_lbl);
  375. }
  376. {
  377. lang_list = memnew(Tree);
  378. lang_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
  379. lang_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  380. lang_list->connect("cell_selected", callable_mp(this, &EditorLocaleDialog::_item_selected));
  381. lang_list->set_columns(1);
  382. lang_list->connect("item_edited", callable_mp(this, &EditorLocaleDialog::_filter_lang_option_changed));
  383. vb_lang_list->add_child(lang_list);
  384. }
  385. hb_lists->add_child(vb_lang_list);
  386. }
  387. {
  388. vb_script_list = memnew(VBoxContainer);
  389. vb_script_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  390. {
  391. Label *script_lbl = memnew(Label);
  392. // TRANSLATORS: This is the label for a list of writing systems.
  393. script_lbl->set_text(TTR("Script:", "Locale"));
  394. vb_script_list->add_child(script_lbl);
  395. }
  396. {
  397. script_list = memnew(Tree);
  398. script_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
  399. script_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  400. script_list->connect("cell_selected", callable_mp(this, &EditorLocaleDialog::_item_selected));
  401. script_list->set_columns(1);
  402. script_list->connect("item_edited", callable_mp(this, &EditorLocaleDialog::_filter_script_option_changed));
  403. vb_script_list->add_child(script_list);
  404. }
  405. hb_lists->add_child(vb_script_list);
  406. }
  407. {
  408. VBoxContainer *vb_cnt_list = memnew(VBoxContainer);
  409. vb_cnt_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  410. {
  411. Label *cnt_lbl = memnew(Label);
  412. cnt_lbl->set_text(TTR("Country:"));
  413. vb_cnt_list->add_child(cnt_lbl);
  414. }
  415. {
  416. cnt_list = memnew(Tree);
  417. cnt_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
  418. cnt_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  419. cnt_list->connect("cell_selected", callable_mp(this, &EditorLocaleDialog::_item_selected));
  420. cnt_list->set_columns(1);
  421. cnt_list->connect("item_edited", callable_mp(this, &EditorLocaleDialog::_filter_cnt_option_changed));
  422. vb_cnt_list->add_child(cnt_list);
  423. }
  424. hb_lists->add_child(vb_cnt_list);
  425. }
  426. vb->add_child(hb_lists);
  427. }
  428. {
  429. hb_locale = memnew(HBoxContainer);
  430. hb_locale->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  431. {
  432. {
  433. VBoxContainer *vb_language = memnew(VBoxContainer);
  434. vb_language->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  435. {
  436. Label *language_lbl = memnew(Label);
  437. language_lbl->set_text(TTR("Language"));
  438. vb_language->add_child(language_lbl);
  439. }
  440. {
  441. lang_code = memnew(LineEdit);
  442. lang_code->set_max_length(3);
  443. lang_code->set_tooltip_text("Language");
  444. vb_language->add_child(lang_code);
  445. }
  446. hb_locale->add_child(vb_language);
  447. }
  448. {
  449. VBoxContainer *vb_script = memnew(VBoxContainer);
  450. vb_script->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  451. {
  452. Label *script_lbl = memnew(Label);
  453. // TRANSLATORS: This refers to a writing system.
  454. script_lbl->set_text(TTR("Script", "Locale"));
  455. vb_script->add_child(script_lbl);
  456. }
  457. {
  458. script_code = memnew(LineEdit);
  459. script_code->set_max_length(4);
  460. script_code->set_tooltip_text("Script");
  461. vb_script->add_child(script_code);
  462. }
  463. hb_locale->add_child(vb_script);
  464. }
  465. {
  466. VBoxContainer *vb_country = memnew(VBoxContainer);
  467. vb_country->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  468. {
  469. Label *country_lbl = memnew(Label);
  470. country_lbl->set_text(TTR("Country"));
  471. vb_country->add_child(country_lbl);
  472. }
  473. {
  474. country_code = memnew(LineEdit);
  475. country_code->set_max_length(2);
  476. country_code->set_tooltip_text("Country");
  477. vb_country->add_child(country_code);
  478. }
  479. hb_locale->add_child(vb_country);
  480. }
  481. {
  482. VBoxContainer *vb_variant = memnew(VBoxContainer);
  483. vb_variant->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  484. {
  485. Label *variant_lbl = memnew(Label);
  486. variant_lbl->set_text(TTR("Variant"));
  487. vb_variant->add_child(variant_lbl);
  488. }
  489. {
  490. variant_code = memnew(LineEdit);
  491. variant_code->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  492. variant_code->set_placeholder("Variant");
  493. variant_code->set_tooltip_text("Variant");
  494. vb_variant->add_child(variant_code);
  495. }
  496. hb_locale->add_child(vb_variant);
  497. }
  498. }
  499. vb->add_child(hb_locale);
  500. }
  501. add_child(vb);
  502. _update_tree();
  503. set_ok_button_text(TTR("Select"));
  504. }