Path: blob/master/editor/translations/editor_locale_dialog.cpp
9896 views
/**************************************************************************/1/* editor_locale_dialog.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "editor_locale_dialog.h"3132#include "core/config/project_settings.h"33#include "core/string/translation_server.h"34#include "editor/editor_undo_redo_manager.h"35#include "editor/themes/editor_scale.h"36#include "scene/gui/check_button.h"37#include "scene/gui/line_edit.h"38#include "scene/gui/option_button.h"39#include "scene/gui/tree.h"4041void EditorLocaleDialog::_notification(int p_what) {42if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {43// TRANSLATORS: This is the label for a list of writing systems.44script_label1->set_text(TTR("Script:", "Locale"));45// TRANSLATORS: This refers to a writing system.46script_label2->set_text(TTR("Script", "Locale"));4748script_list->set_accessibility_name(TTR("Script", "Locale"));49script_code->set_accessibility_name(TTR("Script", "Locale"));50}51}5253void EditorLocaleDialog::_bind_methods() {54ADD_SIGNAL(MethodInfo("locale_selected", PropertyInfo(Variant::STRING, "locale")));55}5657void EditorLocaleDialog::ok_pressed() {58if (edit_filters->is_pressed()) {59return; // Do not update, if in filter edit mode.60}6162String locale;63if (lang_code->get_text().is_empty()) {64return; // Language code is required.65}66locale = lang_code->get_text();6768if (!script_code->get_text().is_empty()) {69locale += "_" + script_code->get_text();70}71if (!country_code->get_text().is_empty()) {72locale += "_" + country_code->get_text();73}74if (!variant_code->get_text().is_empty()) {75locale += "_" + variant_code->get_text();76}7778emit_signal(SNAME("locale_selected"), TranslationServer::get_singleton()->standardize_locale(locale));79hide();80}8182void EditorLocaleDialog::_item_selected() {83if (updating_lists) {84return;85}8687if (edit_filters->is_pressed()) {88return; // Do not update, if in filter edit mode.89}9091TreeItem *l = lang_list->get_selected();92if (l) {93lang_code->set_text(l->get_metadata(0).operator String());94}9596TreeItem *s = script_list->get_selected();97if (s) {98script_code->set_text(s->get_metadata(0).operator String());99}100101TreeItem *c = cnt_list->get_selected();102if (c) {103country_code->set_text(c->get_metadata(0).operator String());104}105}106107void EditorLocaleDialog::_toggle_advanced(bool p_checked) {108if (!p_checked) {109script_code->set_text("");110variant_code->set_text("");111}112_update_tree();113}114115void EditorLocaleDialog::_post_popup() {116ConfirmationDialog::_post_popup();117118if (!locale_set) {119lang_code->set_text("");120script_code->set_text("");121country_code->set_text("");122variant_code->set_text("");123}124edit_filters->set_pressed(false);125_update_tree();126}127128void EditorLocaleDialog::_filter_lang_option_changed() {129TreeItem *t = lang_list->get_edited();130String lang = t->get_metadata(0);131bool checked = t->is_checked(0);132133Variant prev;134Array f_lang_all;135136if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/language_filter")) {137f_lang_all = GLOBAL_GET("internationalization/locale/language_filter");138prev = f_lang_all;139}140141int l_idx = f_lang_all.find(lang);142143if (checked) {144if (l_idx == -1) {145f_lang_all.append(lang);146}147} else {148if (l_idx != -1) {149f_lang_all.remove_at(l_idx);150}151}152153f_lang_all.sort();154155EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();156undo_redo->create_action(TTR("Changed Locale Language Filter"));157undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/language_filter", f_lang_all);158undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/language_filter", prev);159undo_redo->commit_action();160}161162void EditorLocaleDialog::_filter_script_option_changed() {163TreeItem *t = script_list->get_edited();164String scr_code = t->get_metadata(0);165bool checked = t->is_checked(0);166167Variant prev;168Array f_script_all;169170if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/script_filter")) {171f_script_all = GLOBAL_GET("internationalization/locale/script_filter");172prev = f_script_all;173}174175int l_idx = f_script_all.find(scr_code);176177if (checked) {178if (l_idx == -1) {179f_script_all.append(scr_code);180}181} else {182if (l_idx != -1) {183f_script_all.remove_at(l_idx);184}185}186187f_script_all.sort();188189EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();190undo_redo->create_action(TTR("Changed Locale Script Filter"));191undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/script_filter", f_script_all);192undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/script_filter", prev);193undo_redo->commit_action();194}195196void EditorLocaleDialog::_filter_cnt_option_changed() {197TreeItem *t = cnt_list->get_edited();198String cnt = t->get_metadata(0);199bool checked = t->is_checked(0);200201Variant prev;202Array f_cnt_all;203204if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/country_filter")) {205f_cnt_all = GLOBAL_GET("internationalization/locale/country_filter");206prev = f_cnt_all;207}208209int l_idx = f_cnt_all.find(cnt);210211if (checked) {212if (l_idx == -1) {213f_cnt_all.append(cnt);214}215} else {216if (l_idx != -1) {217f_cnt_all.remove_at(l_idx);218}219}220221f_cnt_all.sort();222223EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();224undo_redo->create_action(TTR("Changed Locale Country Filter"));225undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/country_filter", f_cnt_all);226undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/country_filter", prev);227undo_redo->commit_action();228}229230void EditorLocaleDialog::_filter_mode_changed(int p_mode) {231int f_mode = filter_mode->get_selected_id();232Variant prev;233234if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter_mode")) {235prev = GLOBAL_GET("internationalization/locale/locale_filter_mode");236}237238EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();239undo_redo->create_action(TTR("Changed Locale Filter Mode"));240undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter_mode", f_mode);241undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter_mode", prev);242undo_redo->commit_action();243244_update_tree();245}246247void EditorLocaleDialog::_edit_filters(bool p_checked) {248_update_tree();249}250251void EditorLocaleDialog::_update_tree() {252updating_lists = true;253254int filter = SHOW_ALL_LOCALES;255if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter_mode")) {256filter = GLOBAL_GET_CACHED(int, "internationalization/locale/locale_filter_mode");257}258Array f_lang_all;259if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/language_filter")) {260f_lang_all = GLOBAL_GET("internationalization/locale/language_filter");261}262Array f_cnt_all;263if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/country_filter")) {264f_cnt_all = GLOBAL_GET("internationalization/locale/country_filter");265}266Array f_script_all;267if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/script_filter")) {268f_script_all = GLOBAL_GET("internationalization/locale/script_filter");269}270bool is_edit_mode = edit_filters->is_pressed();271272filter_mode->select(filter);273274// Hide text advanced edit and disable OK button if in filter edit mode.275advanced->set_visible(!is_edit_mode);276hb_locale->set_visible(!is_edit_mode && advanced->is_pressed());277vb_script_list->set_visible(advanced->is_pressed());278get_ok_button()->set_disabled(is_edit_mode);279280// Update language list.281lang_list->clear();282TreeItem *l_root = lang_list->create_item(nullptr);283lang_list->set_hide_root(true);284285Vector<String> languages = TranslationServer::get_singleton()->get_all_languages();286for (const String &E : languages) {287if (is_edit_mode || (filter == SHOW_ALL_LOCALES) || f_lang_all.has(E) || f_lang_all.is_empty()) {288const String &lang = TranslationServer::get_singleton()->get_language_name(E);289TreeItem *t = lang_list->create_item(l_root);290if (is_edit_mode) {291t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);292t->set_editable(0, true);293t->set_checked(0, f_lang_all.has(E));294} else if (lang_code->get_text() == E) {295t->select(0);296}297t->set_text(0, vformat("%s [%s]", lang, E));298t->set_metadata(0, E);299}300}301302// Update script list.303script_list->clear();304TreeItem *s_root = script_list->create_item(nullptr);305script_list->set_hide_root(true);306307if (!is_edit_mode) {308TreeItem *t = script_list->create_item(s_root);309t->set_text(0, TTRC("[Default]"));310t->set_metadata(0, "");311}312313Vector<String> scripts = TranslationServer::get_singleton()->get_all_scripts();314for (const String &E : scripts) {315if (is_edit_mode || (filter == SHOW_ALL_LOCALES) || f_script_all.has(E) || f_script_all.is_empty()) {316const String &scr_code = TranslationServer::get_singleton()->get_script_name(E);317TreeItem *t = script_list->create_item(s_root);318if (is_edit_mode) {319t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);320t->set_editable(0, true);321t->set_checked(0, f_script_all.has(E));322} else if (script_code->get_text() == E) {323t->select(0);324}325t->set_text(0, vformat("%s [%s]", scr_code, E));326t->set_metadata(0, E);327}328}329330// Update country list.331cnt_list->clear();332TreeItem *c_root = cnt_list->create_item(nullptr);333cnt_list->set_hide_root(true);334335if (!is_edit_mode) {336TreeItem *t = cnt_list->create_item(c_root);337t->set_text(0, TTRC("[Default]"));338t->set_metadata(0, "");339}340341Vector<String> countries = TranslationServer::get_singleton()->get_all_countries();342for (const String &E : countries) {343if (is_edit_mode || (filter == SHOW_ALL_LOCALES) || f_cnt_all.has(E) || f_cnt_all.is_empty()) {344const String &cnt = TranslationServer::get_singleton()->get_country_name(E);345TreeItem *t = cnt_list->create_item(c_root);346if (is_edit_mode) {347t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);348t->set_editable(0, true);349t->set_checked(0, f_cnt_all.has(E));350} else if (country_code->get_text() == E) {351t->select(0);352}353t->set_text(0, vformat("%s [%s]", cnt, E));354t->set_metadata(0, E);355}356}357updating_lists = false;358}359360void EditorLocaleDialog::set_locale(const String &p_locale) {361const String &locale = TranslationServer::get_singleton()->standardize_locale(p_locale);362if (locale.is_empty()) {363locale_set = false;364365lang_code->set_text("");366script_code->set_text("");367country_code->set_text("");368variant_code->set_text("");369} else {370locale_set = true;371372Vector<String> locale_elements = p_locale.split("_");373lang_code->set_text(locale_elements[0]);374if (locale_elements.size() >= 2) {375if (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])) {376script_code->set_text(locale_elements[1]);377advanced->set_pressed(true);378}379if (locale_elements[1].length() == 2 && is_ascii_upper_case(locale_elements[1][0]) && is_ascii_upper_case(locale_elements[1][1])) {380country_code->set_text(locale_elements[1]);381}382}383if (locale_elements.size() >= 3) {384if (locale_elements[2].length() == 2 && is_ascii_upper_case(locale_elements[2][0]) && is_ascii_upper_case(locale_elements[2][1])) {385country_code->set_text(locale_elements[2]);386} else {387variant_code->set_text(locale_elements[2].to_lower());388advanced->set_pressed(true);389}390}391if (locale_elements.size() >= 4) {392variant_code->set_text(locale_elements[3].to_lower());393advanced->set_pressed(true);394}395}396}397398void EditorLocaleDialog::popup_locale_dialog() {399popup_centered_clamped(Size2(1050, 700) * EDSCALE, 0.8);400}401402EditorLocaleDialog::EditorLocaleDialog() {403set_title(TTRC("Select a Locale"));404405VBoxContainer *vb = memnew(VBoxContainer);406{407HBoxContainer *hb_filter = memnew(HBoxContainer);408{409filter_mode = memnew(OptionButton);410filter_mode->set_accessibility_name(TTRC("Locale Filter"));411filter_mode->add_item(TTRC("Show All Locales"), SHOW_ALL_LOCALES);412filter_mode->set_h_size_flags(Control::SIZE_EXPAND_FILL);413filter_mode->add_item(TTRC("Show Selected Locales Only"), SHOW_ONLY_SELECTED_LOCALES);414filter_mode->select(0);415filter_mode->connect(SceneStringName(item_selected), callable_mp(this, &EditorLocaleDialog::_filter_mode_changed));416hb_filter->add_child(filter_mode);417}418{419edit_filters = memnew(CheckButton);420edit_filters->set_text(TTRC("Edit Filters"));421edit_filters->set_toggle_mode(true);422edit_filters->set_pressed(false);423edit_filters->connect(SceneStringName(toggled), callable_mp(this, &EditorLocaleDialog::_edit_filters));424hb_filter->add_child(edit_filters);425}426{427advanced = memnew(CheckButton);428advanced->set_text(TTRC("Advanced"));429advanced->set_toggle_mode(true);430advanced->set_pressed(false);431advanced->connect(SceneStringName(toggled), callable_mp(this, &EditorLocaleDialog::_toggle_advanced));432hb_filter->add_child(advanced);433}434vb->add_child(hb_filter);435}436{437HBoxContainer *hb_lists = memnew(HBoxContainer);438hb_lists->set_v_size_flags(Control::SIZE_EXPAND_FILL);439{440VBoxContainer *vb_lang_list = memnew(VBoxContainer);441vb_lang_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);442{443Label *lang_lbl = memnew(Label);444lang_lbl->set_text(TTRC("Language:"));445vb_lang_list->add_child(lang_lbl);446}447{448lang_list = memnew(Tree);449lang_list->set_accessibility_name(TTRC("Language:"));450lang_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);451lang_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);452lang_list->connect("cell_selected", callable_mp(this, &EditorLocaleDialog::_item_selected));453lang_list->set_columns(1);454lang_list->connect("item_edited", callable_mp(this, &EditorLocaleDialog::_filter_lang_option_changed));455vb_lang_list->add_child(lang_list);456}457hb_lists->add_child(vb_lang_list);458}459{460vb_script_list = memnew(VBoxContainer);461vb_script_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);462{463script_label1 = memnew(Label);464script_label1->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);465vb_script_list->add_child(script_label1);466}467{468script_list = memnew(Tree);469script_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);470script_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);471script_list->connect("cell_selected", callable_mp(this, &EditorLocaleDialog::_item_selected));472script_list->set_columns(1);473script_list->connect("item_edited", callable_mp(this, &EditorLocaleDialog::_filter_script_option_changed));474vb_script_list->add_child(script_list);475}476hb_lists->add_child(vb_script_list);477}478{479VBoxContainer *vb_cnt_list = memnew(VBoxContainer);480vb_cnt_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);481{482Label *cnt_lbl = memnew(Label);483cnt_lbl->set_text(TTRC("Country:"));484vb_cnt_list->add_child(cnt_lbl);485}486{487cnt_list = memnew(Tree);488cnt_list->set_accessibility_name(TTRC("Country:"));489cnt_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);490cnt_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);491cnt_list->connect("cell_selected", callable_mp(this, &EditorLocaleDialog::_item_selected));492cnt_list->set_columns(1);493cnt_list->connect("item_edited", callable_mp(this, &EditorLocaleDialog::_filter_cnt_option_changed));494vb_cnt_list->add_child(cnt_list);495}496hb_lists->add_child(vb_cnt_list);497}498vb->add_child(hb_lists);499}500{501hb_locale = memnew(HBoxContainer);502hb_locale->set_h_size_flags(Control::SIZE_EXPAND_FILL);503{504{505VBoxContainer *vb_language = memnew(VBoxContainer);506vb_language->set_h_size_flags(Control::SIZE_EXPAND_FILL);507{508Label *language_lbl = memnew(Label);509language_lbl->set_text(TTRC("Language"));510vb_language->add_child(language_lbl);511}512{513lang_code = memnew(LineEdit);514lang_code->set_max_length(3);515lang_code->set_accessibility_name("Language");516vb_language->add_child(lang_code);517}518hb_locale->add_child(vb_language);519}520{521VBoxContainer *vb_script = memnew(VBoxContainer);522vb_script->set_h_size_flags(Control::SIZE_EXPAND_FILL);523{524script_label2 = memnew(Label);525script_label2->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);526vb_script->add_child(script_label2);527}528{529script_code = memnew(LineEdit);530script_code->set_max_length(4);531vb_script->add_child(script_code);532}533hb_locale->add_child(vb_script);534}535{536VBoxContainer *vb_country = memnew(VBoxContainer);537vb_country->set_h_size_flags(Control::SIZE_EXPAND_FILL);538{539Label *country_lbl = memnew(Label);540country_lbl->set_text(TTRC("Country"));541vb_country->add_child(country_lbl);542}543{544country_code = memnew(LineEdit);545country_code->set_max_length(2);546country_code->set_tooltip_text("Country");547vb_country->add_child(country_code);548}549hb_locale->add_child(vb_country);550}551{552VBoxContainer *vb_variant = memnew(VBoxContainer);553vb_variant->set_h_size_flags(Control::SIZE_EXPAND_FILL);554{555Label *variant_lbl = memnew(Label);556variant_lbl->set_text(TTRC("Variant"));557vb_variant->add_child(variant_lbl);558}559{560variant_code = memnew(LineEdit);561variant_code->set_h_size_flags(Control::SIZE_EXPAND_FILL);562variant_code->set_placeholder("Variant");563variant_code->set_accessibility_name("Variant");564vb_variant->add_child(variant_code);565}566hb_locale->add_child(vb_variant);567}568}569vb->add_child(hb_locale);570}571add_child(vb);572_update_tree();573574set_ok_button_text(TTRC("Select"));575}576577578