/**************************************************************************/ /* script_text_editor.cpp */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /**************************************************************************/ /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ #include "script_text_editor.h" #include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/dir_access.h" #include "core/io/json.h" #include "core/math/expression.h" #include "core/os/keyboard.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/doc/editor_help.h" #include "editor/docks/filesystem_dock.h" #include "editor/editor_interface.h" #include "editor/editor_node.h" #include "editor/editor_string_names.h" #include "editor/gui/editor_toaster.h" #include "editor/inspector/editor_context_menu_plugin.h" #include "editor/inspector/editor_inspector.h" #include "editor/inspector/multi_node_edit.h" #include "editor/script/syntax_highlighters.h" #include "editor/settings/editor_command_palette.h" #include "editor/settings/editor_settings.h" #include "editor/themes/editor_scale.h" #include "scene/gui/grid_container.h" #include "scene/gui/menu_button.h" #include "scene/gui/rich_text_label.h" #include "scene/gui/split_container.h" void ConnectionInfoDialog::ok_pressed() { } void ConnectionInfoDialog::popup_connections(const String &p_method, const Vector &p_nodes) { method->set_text(p_method); tree->clear(); TreeItem *root = tree->create_item(); for (int i = 0; i < p_nodes.size(); i++) { List all_connections; p_nodes[i]->get_signals_connected_to_this(&all_connections); for (const Connection &connection : all_connections) { if (connection.callable.get_method() != p_method) { continue; } TreeItem *node_item = tree->create_item(root); node_item->set_text(0, Object::cast_to(connection.signal.get_object())->get_name()); node_item->set_icon(0, EditorNode::get_singleton()->get_object_icon(connection.signal.get_object())); node_item->set_selectable(0, false); node_item->set_editable(0, false); node_item->set_text(1, connection.signal.get_name()); Control *p = Object::cast_to(get_parent()); node_item->set_icon(1, p->get_editor_theme_icon(SNAME("Slot"))); node_item->set_selectable(1, false); node_item->set_editable(1, false); node_item->set_text(2, Object::cast_to(connection.callable.get_object())->get_name()); node_item->set_icon(2, EditorNode::get_singleton()->get_object_icon(connection.callable.get_object())); node_item->set_selectable(2, false); node_item->set_editable(2, false); } } popup_centered(Size2(600, 300) * EDSCALE); } ConnectionInfoDialog::ConnectionInfoDialog() { set_title(TTRC("Connections to method:")); VBoxContainer *vbc = memnew(VBoxContainer); vbc->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 8 * EDSCALE); vbc->set_anchor_and_offset(SIDE_TOP, Control::ANCHOR_BEGIN, 8 * EDSCALE); vbc->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -8 * EDSCALE); vbc->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_END, -8 * EDSCALE); add_child(vbc); method = memnew(Label); method->set_focus_mode(Control::FOCUS_ACCESSIBILITY); method->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); method->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); vbc->add_child(method); tree = memnew(Tree); tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); tree->set_theme_type_variation("TreeTable"); tree->set_hide_folding(true); tree->set_columns(3); tree->set_hide_root(true); tree->set_column_titles_visible(true); tree->set_column_title(0, TTRC("Source")); tree->set_column_title(1, TTRC("Signal")); tree->set_column_title(2, TTRC("Target")); vbc->add_child(tree); tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); tree->set_allow_rmb_select(true); } //////////////////////////////////////////////////////////////////////////////// void ScriptTextEditor::EditMenusSTE::_update_breakpoint_list() { TextEditorBase *script_text_editor = _get_active_editor(); ERR_FAIL_NULL(script_text_editor); breakpoints_menu->clear(); breakpoints_menu->reset_size(); breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_breakpoint"), DEBUG_TOGGLE_BREAKPOINT); breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_breakpoints"), DEBUG_REMOVE_ALL_BREAKPOINTS); breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_breakpoint"), DEBUG_GOTO_NEXT_BREAKPOINT); breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_breakpoint"), DEBUG_GOTO_PREV_BREAKPOINT); PackedInt32Array breakpoint_list = script_text_editor->get_code_editor()->get_text_editor()->get_breakpointed_lines(); if (breakpoint_list.is_empty()) { return; } breakpoints_menu->add_separator(); for (int i = 0; i < breakpoint_list.size(); i++) { // Strip edges to remove spaces or tabs. // Also replace any tabs by spaces, since we can't print tabs in the menu. String line = script_text_editor->get_code_editor()->get_text_editor()->get_line(breakpoint_list[i]).replace("\t", " ").strip_edges(); // Limit the size of the line if too big. if (line.length() > 50) { line = line.substr(0, 50); } breakpoints_menu->add_item(String::num_int64(breakpoint_list[i] + 1) + " - `" + line + "`"); breakpoints_menu->set_item_metadata(-1, breakpoint_list[i]); } } void ScriptTextEditor::EditMenusSTE::_breakpoint_item_pressed(int p_idx) { TextEditorBase *script_text_editor = _get_active_editor(); ERR_FAIL_NULL(script_text_editor); if (p_idx < 4) { // Any item before the separator. _edit_option(breakpoints_menu->get_item_id(p_idx)); } else { script_text_editor->get_code_editor()->goto_line_centered(breakpoints_menu->get_item_metadata(p_idx)); } } ScriptTextEditor::EditMenusSTE::EditMenusSTE() { edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE); _popup_move_item(EDIT_DUPLICATE_LINES, edit_menu->get_popup()); goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_function"), SEARCH_LOCATE_FUNCTION); _popup_move_item(SEARCH_GOTO_LINE, goto_menu->get_popup(), false); goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_symbol"), LOOKUP_SYMBOL); _popup_move_item(SEARCH_GOTO_LINE, goto_menu->get_popup()); edit_menu_fold->add_shortcut(ED_GET_SHORTCUT("script_text_editor/create_code_region"), EDIT_CREATE_CODE_REGION); edit_menu_convert_indent->add_shortcut(ED_GET_SHORTCUT("script_text_editor/auto_indent"), EDIT_AUTO_INDENT); search_menu->get_popup()->add_separator(); search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/contextual_help"), HELP_CONTEXTUAL); breakpoints_menu = memnew(PopupMenu); goto_menu->get_popup()->add_submenu_node_item(TTRC("Breakpoints"), breakpoints_menu); breakpoints_menu->connect("about_to_popup", callable_mp(this, &EditMenusSTE::_update_breakpoint_list)); breakpoints_menu->connect("index_pressed", callable_mp(this, &EditMenusSTE::_breakpoint_item_pressed)); } //////////////////////////////////////////////////////////////////////////////// Vector ScriptTextEditor::get_functions() { CodeEdit *te = code_editor->get_text_editor(); String text = te->get_text(); List fnc; Ref