diff options
-rw-r--r-- | core/translation.cpp | 136 | ||||
-rw-r--r-- | core/translation.h | 3 | ||||
-rw-r--r-- | editor/editor_settings.cpp | 1 | ||||
-rw-r--r-- | methods.py | 10 | ||||
-rw-r--r-- | modules/mono/SCsub | 38 | ||||
-rw-r--r-- | modules/mono/editor/godotsharp_builds.cpp | 14 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_assembly.cpp | 7 | ||||
-rw-r--r-- | scene/gui/line_edit.cpp | 105 | ||||
-rw-r--r-- | scene/gui/line_edit.h | 14 |
9 files changed, 205 insertions, 123 deletions
diff --git a/core/translation.cpp b/core/translation.cpp index 54dbaf6ed5..058db956e5 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -753,65 +753,17 @@ static const char *locale_names[] = { 0 }; -bool TranslationServer::is_locale_valid(const String &p_locale) { - - const char **ptr = locale_list; - - while (*ptr) { - - if (*ptr == p_locale) - return true; - ptr++; - } - - return false; -} - -Vector<String> TranslationServer::get_all_locales() { - - Vector<String> locales; - - const char **ptr = locale_list; - - while (*ptr) { - locales.push_back(*ptr); - ptr++; - } - - return locales; -} - -Vector<String> TranslationServer::get_all_locale_names() { - - Vector<String> locales; - - const char **ptr = locale_names; - - while (*ptr) { - locales.push_back(*ptr); - ptr++; - } - - return locales; -} +static const char *locale_renames[][2] = { + { "no", "nb" }, + { NULL, NULL } +}; static String get_trimmed_locale(const String &p_locale) { return p_locale.substr(0, 2); } -static bool is_valid_locale(const String &p_locale) { - - const char **ptr = locale_list; - - while (*ptr) { - if (p_locale == *ptr) - return true; - ptr++; - } - - return false; -} +/////////////////////////////////////////////// PoolVector<String> Translation::_get_messages() const { @@ -857,14 +809,13 @@ void Translation::_set_messages(const PoolVector<String> &p_messages) { void Translation::set_locale(const String &p_locale) { - // replaces '-' with '_' for macOS Sierra-style locales - String univ_locale = p_locale.replace("-", "_"); + String univ_locale = TranslationServer::standardize_locale(p_locale); - if (!is_valid_locale(univ_locale)) { + if (!TranslationServer::is_locale_valid(univ_locale)) { String trimmed_locale = get_trimmed_locale(univ_locale); - ERR_EXPLAIN("Invalid Locale: " + trimmed_locale); - ERR_FAIL_COND(!is_valid_locale(trimmed_locale)); + ERR_EXPLAIN("Invalid locale: " + trimmed_locale); + ERR_FAIL_COND(!TranslationServer::is_locale_valid(trimmed_locale)); locale = trimmed_locale; } else { @@ -929,16 +880,47 @@ Translation::Translation() /////////////////////////////////////////////// -void TranslationServer::set_locale(const String &p_locale) { +bool TranslationServer::is_locale_valid(const String &p_locale) { + + const char **ptr = locale_list; + + while (*ptr) { + + if (*ptr == p_locale) + return true; + ptr++; + } + + return false; +} - // replaces '-' with '_' for macOS Sierra-style locales +String TranslationServer::standardize_locale(const String &p_locale) { + + // Replaces '-' with '_' for macOS Sierra-style locales String univ_locale = p_locale.replace("-", "_"); - if (!is_valid_locale(univ_locale)) { + // Handles known non-ISO locale names used e.g. on Windows + int idx = 0; + while (locale_renames[idx][0] != NULL) { + if (locale_renames[idx][0] == univ_locale) { + univ_locale = locale_renames[idx][1]; + break; + } + idx++; + } + + return univ_locale; +} + +void TranslationServer::set_locale(const String &p_locale) { + + String univ_locale = standardize_locale(p_locale); + + if (!is_locale_valid(univ_locale)) { String trimmed_locale = get_trimmed_locale(univ_locale); - ERR_EXPLAIN("Invalid Locale: " + trimmed_locale); - ERR_FAIL_COND(!is_valid_locale(trimmed_locale)); + ERR_EXPLAIN("Invalid locale: " + trimmed_locale); + ERR_FAIL_COND(!is_locale_valid(trimmed_locale)); locale = trimmed_locale; } else { @@ -963,6 +945,34 @@ String TranslationServer::get_locale_name(const String &p_locale) const { return locale_name_map[p_locale]; } +Vector<String> TranslationServer::get_all_locales() { + + Vector<String> locales; + + const char **ptr = locale_list; + + while (*ptr) { + locales.push_back(*ptr); + ptr++; + } + + return locales; +} + +Vector<String> TranslationServer::get_all_locale_names() { + + Vector<String> locales; + + const char **ptr = locale_names; + + while (*ptr) { + locales.push_back(*ptr); + ptr++; + } + + return locales; +} + void TranslationServer::add_translation(const Ref<Translation> &p_translation) { translations.insert(p_translation); diff --git a/core/translation.h b/core/translation.h index 5fec1d9f45..0cdab3b0bc 100644 --- a/core/translation.h +++ b/core/translation.h @@ -85,8 +85,6 @@ class TranslationServer : public Object { public: _FORCE_INLINE_ static TranslationServer *get_singleton() { return singleton; } - //yes, portuguese is supported! - void set_enabled(bool p_enabled) { enabled = p_enabled; } _FORCE_INLINE_ bool is_enabled() const { return enabled; } @@ -103,6 +101,7 @@ public: static Vector<String> get_all_locales(); static Vector<String> get_all_locale_names(); static bool is_locale_valid(const String &p_locale); + static String standardize_locale(const String &p_locale); void set_tool_translation(const Ref<Translation> &p_translation); StringName tool_translate(const StringName &p_message) const; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 799a8a2eb8..78cc215421 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -544,6 +544,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { { String lang_hint = "en"; String host_lang = OS::get_singleton()->get_locale(); + host_lang = TranslationServer::standardize_locale(host_lang); String best; diff --git a/methods.py b/methods.py index 0ae831f942..b62dfc6544 100644 --- a/methods.py +++ b/methods.py @@ -1710,9 +1710,13 @@ def generate_vs_project(env, num_jobs): env.AddToVSProject(env.servers_sources) env.AddToVSProject(env.editor_sources) - env['MSVSBUILDCOM'] = build_commandline('scons --directory="$(ProjectDir)" platform=windows target=$(Configuration) tools=!tools! -j' + str(num_jobs)) - env['MSVSREBUILDCOM'] = build_commandline('scons --directory="$(ProjectDir)" platform=windows target=$(Configuration) tools=!tools! vsproj=yes -j' + str(num_jobs)) - env['MSVSCLEANCOM'] = build_commandline('scons --directory="$(ProjectDir)" --clean platform=windows target=$(Configuration) tools=!tools! -j' + str(num_jobs)) + # windows allows us to have spaces in paths, so we need + # to double quote off the directory. However, the path ends + # in a backslash, so we need to remove this, lest it escape the + # last double quote off, confusing MSBuild + env['MSVSBUILDCOM'] = build_commandline('scons --directory="$(ProjectDir.TrimEnd(\'\\\'))" platform=windows target=$(Configuration) tools=!tools! -j' + str(num_jobs)) + env['MSVSREBUILDCOM'] = build_commandline('scons --directory="$(ProjectDir.TrimEnd(\'\\\'))" platform=windows target=$(Configuration) tools=!tools! vsproj=yes -j' + str(num_jobs)) + env['MSVSCLEANCOM'] = build_commandline('scons --directory="$(ProjectDir.TrimEnd(\'\\\'))" --clean platform=windows target=$(Configuration) tools=!tools! -j' + str(num_jobs)) # This version information (Win32, x64, Debug, Release, Release_Debug seems to be # required for Visual Studio to understand that it needs to generate an NMAKE diff --git a/modules/mono/SCsub b/modules/mono/SCsub index 9f90a7b70c..27e60c4623 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -97,29 +97,31 @@ def find_msbuild_unix(filename): def find_msbuild_windows(): import mono_reg_utils as monoreg - msbuild_tools_path = monoreg.find_msbuild_tools_path_reg() + bits = env['bits'] - if msbuild_tools_path: - return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), '') + if bits == '32': + if os.getenv('MONO32_PREFIX'): + mono_root = os.getenv('MONO32_PREFIX') + else: + mono_root = monoreg.find_mono_root_dir(bits) else: - bits = env['bits'] - - if bits == '32': - if os.getenv('MONO32_PREFIX'): - mono_root = os.getenv('MONO32_PREFIX') - else: - mono_root = monoreg.find_mono_root_dir(bits) + if os.getenv('MONO64_PREFIX'): + mono_root = os.getenv('MONO64_PREFIX') else: - if os.getenv('MONO64_PREFIX'): - mono_root = os.getenv('MONO64_PREFIX') - else: - mono_root = monoreg.find_mono_root_dir(bits) + mono_root = monoreg.find_mono_root_dir(bits) - if mono_root: - msbuild_mono = os.path.join(mono_root, 'bin', 'msbuild.bat') + if not mono_root: + raise RuntimeError('Cannot find mono root directory') + + msbuild_tools_path = monoreg.find_msbuild_tools_path_reg() + + if msbuild_tools_path: + return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), os.path.join(mono_root, 'lib', 'mono', '4.5')) + else: + msbuild_mono = os.path.join(mono_root, 'bin', 'msbuild.bat') - if os.path.isfile(msbuild_mono): - return (msbuild_mono, os.path.join(mono_root, 'lib', 'mono', '4.5')) + if os.path.isfile(msbuild_mono): + return (msbuild_mono, '') return None diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index aaea1bc839..83d2bb1471 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -32,6 +32,7 @@ #include "main/main.h" #include "../godotsharp_dirs.h" +#include "../mono_gd/gd_mono.h" #include "../mono_gd/gd_mono_class.h" #include "../mono_gd/gd_mono_marshal.h" #include "../utils/path_utils.h" @@ -84,10 +85,16 @@ void godot_icall_BuildInstance_get_MSBuildInfo(MonoString **r_msbuild_path, Mono if (!msbuild_tools_path.ends_with("\\")) msbuild_tools_path += "\\"; - *r_msbuild_path = GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe"); - // FrameworkPathOverride - *r_framework_path = GDMonoMarshal::mono_string_from_godot(GDMono::get_singleton()->get_mono_reg_info().assembly_dir); + const MonoRegInfo &mono_reg_info = GDMono::get_singleton()->get_mono_reg_info(); + if (mono_reg_info.assembly_dir.length()) { + *r_msbuild_path = GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe"); + + String framework_path = path_join(mono_reg_info.assembly_dir, "mono", "4.5"); + *r_framework_path = GDMonoMarshal::mono_string_from_godot(framework_path); + } else { + ERR_PRINT("Cannot find Mono's assemblies directory in the registry"); + } return; } @@ -130,6 +137,7 @@ void godot_icall_BuildInstance_get_MSBuildInfo(MonoString **r_msbuild_path, Mono return; #else + ERR_PRINT("Not implemented on this platform"); return; #endif } diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 0d9b137f99..7dc7043eec 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -107,10 +107,11 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse search_dirs.push_back(String(rootdir).plus_file("mono").plus_file("4.5")); } - while (assemblies_path) { - if (*assemblies_path) + if (assemblies_path) { + while (*assemblies_path) { search_dirs.push_back(*assemblies_path); - ++assemblies_path; + ++assemblies_path; + } } } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index ed8eff436c..f57f58c18d 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -161,13 +161,14 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { } break; - case (KEY_Z): { // Simple One level undo - + case (KEY_Z): { // undo / redo if (editable) { - - undo(); + if (k->get_shift()) { + redo(); + } else { + undo(); + } } - } break; case (KEY_U): { // Delete from start to cursor @@ -175,7 +176,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { if (editable) { selection_clear(); - undo_text = text; text = text.substr(cursor_pos, text.length() - cursor_pos); Ref<Font> font = get_font("font"); @@ -205,7 +205,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { if (editable) { selection_clear(); - undo_text = text; text = text.substr(0, cursor_pos); _text_changed(); } @@ -245,7 +244,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { break; if (selection.enabled) { - undo_text = text; selection_delete(); break; } @@ -276,7 +274,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { set_cursor_position(cc); } else { - undo_text = text; delete_char(); } @@ -382,7 +379,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { } if (selection.enabled) { - undo_text = text; selection_delete(); break; } @@ -417,7 +413,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { delete_text(cursor_pos, cc); } else { - undo_text = text; set_cursor_position(cursor_pos + 1); delete_char(); } @@ -778,7 +773,6 @@ void LineEdit::copy_text() { void LineEdit::cut_text() { if (selection.enabled) { - undo_text = text; OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin)); selection_delete(); } @@ -798,23 +792,33 @@ void LineEdit::paste_text() { } void LineEdit::undo() { - - int old_cursor_pos = cursor_pos; - text = undo_text; - - Ref<Font> font = get_font("font"); - - cached_width = 0; - for (int i = 0; i < text.length(); i++) - cached_width += font->get_char_size(text[i]).width; - - if (old_cursor_pos > text.length()) { - set_cursor_position(text.length()); - } else { - set_cursor_position(old_cursor_pos); + if (undo_stack_pos == NULL) { + if (undo_stack.size() <= 1) { + return; + } + undo_stack_pos = undo_stack.back(); + } else if (undo_stack_pos == undo_stack.front()) { + return; } + undo_stack_pos = undo_stack_pos->prev(); + TextOperation op = undo_stack_pos->get(); + text = op.text; + set_cursor_position(op.cursor_pos); + _emit_text_change(); +} - _text_changed(); +void LineEdit::redo() { + if (undo_stack_pos == NULL) { + return; + } + if (undo_stack_pos == undo_stack.back()) { + return; + } + undo_stack_pos = undo_stack_pos->next(); + TextOperation op = undo_stack_pos->get(); + text = op.text; + set_cursor_position(op.cursor_pos); + _emit_text_change(); } void LineEdit::shift_selection_check_pre(bool p_shift) { @@ -947,8 +951,6 @@ void LineEdit::delete_char() { void LineEdit::delete_text(int p_from_column, int p_to_column) { - undo_text = text; - if (text.size() > 0) { Ref<Font> font = get_font("font"); if (font != NULL) { @@ -1086,8 +1088,6 @@ void LineEdit::append_at_cursor(String p_text) { if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) { - undo_text = text; - Ref<Font> font = get_font("font"); if (font != NULL) { for (int i = 0; i < p_text.length(); i++) @@ -1105,6 +1105,7 @@ void LineEdit::append_at_cursor(String p_text) { void LineEdit::clear_internal() { + _clear_undo_stack(); cached_width = 0; cursor_pos = 0; window_pos = 0; @@ -1275,6 +1276,11 @@ void LineEdit::menu_option(int p_option) { undo(); } } break; + case MENU_REDO: { + if (editable) { + redo(); + } + } } } @@ -1312,10 +1318,43 @@ void LineEdit::_text_changed() { if (expand_to_text_length) minimum_size_changed(); + _emit_text_change(); + _clear_redo(); +} + +void LineEdit::_emit_text_change() { emit_signal("text_changed", text); _change_notify("text"); } +void LineEdit::_clear_redo() { + _create_undo_state(); + if (undo_stack_pos == NULL) { + return; + } + + undo_stack_pos = undo_stack_pos->next(); + while (undo_stack_pos) { + List<TextOperation>::Element *elem = undo_stack_pos; + undo_stack_pos = undo_stack_pos->next(); + undo_stack.erase(elem); + } + _create_undo_state(); +} + +void LineEdit::_clear_undo_stack() { + undo_stack.clear(); + undo_stack_pos = NULL; + _create_undo_state(); +} + +void LineEdit::_create_undo_state() { + TextOperation op; + op.text = text; + op.cursor_pos = cursor_pos; + undo_stack.push_back(op); +} + void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_toggle_draw_caret"), &LineEdit::_toggle_draw_caret); @@ -1369,6 +1408,7 @@ void LineEdit::_bind_methods() { BIND_ENUM_CONSTANT(MENU_CLEAR); BIND_ENUM_CONSTANT(MENU_SELECT_ALL); BIND_ENUM_CONSTANT(MENU_UNDO); + BIND_ENUM_CONSTANT(MENU_REDO); BIND_ENUM_CONSTANT(MENU_MAX); ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); @@ -1388,6 +1428,8 @@ void LineEdit::_bind_methods() { LineEdit::LineEdit() { + undo_stack_pos = NULL; + _create_undo_state(); align = ALIGN_LEFT; cached_width = 0; cursor_pos = 0; @@ -1421,6 +1463,7 @@ LineEdit::LineEdit() { menu->add_item(TTR("Clear"), MENU_CLEAR); menu->add_separator(); menu->add_item(TTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z); + menu->add_item(TTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z); menu->connect("id_pressed", this, "menu_option"); expand_to_text_length = false; } diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 661f9b60b9..bece29a37d 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -56,6 +56,7 @@ public: MENU_CLEAR, MENU_SELECT_ALL, MENU_UNDO, + MENU_REDO, MENU_MAX }; @@ -92,10 +93,22 @@ private: bool drag_attempt; } selection; + struct TextOperation { + int cursor_pos; + String text; + }; + List<TextOperation> undo_stack; + List<TextOperation>::Element *undo_stack_pos; + + void _clear_undo_stack(); + void _clear_redo(); + void _create_undo_state(); + Timer *caret_blink_timer; static void _ime_text_callback(void *p_self, String p_text, Point2 p_selection); void _text_changed(); + void _emit_text_change(); bool expand_to_text_length; bool caret_blink_enabled; @@ -166,6 +179,7 @@ public: void cut_text(); void paste_text(); void undo(); + void redo(); void set_editable(bool p_editable); bool is_editable() const; |