|
@@ -711,27 +711,65 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
|
|
|
bool warning = err[9];
|
|
|
bool e;
|
|
|
String time = String("%d:%02d:%02d:%04d").sprintf(vals, &e);
|
|
|
- String txt = time + " - " + (err[8].is_zero() ? String(err[7]) : String(err[8]));
|
|
|
+ String txt = err[8].is_zero() ? String(err[7]) : String(err[8]);
|
|
|
|
|
|
- String tooltip = TTR("Type:") + String(warning ? TTR("Warning") : TTR("Error"));
|
|
|
- tooltip += "\n" + TTR("Description:") + " " + String(err[8]);
|
|
|
- tooltip += "\n" + TTR("Time:") + " " + time;
|
|
|
- tooltip += "\nC " + TTR("Error:") + " " + String(err[7]);
|
|
|
- tooltip += "\nC " + TTR("Source:") + " " + String(err[5]) + ":" + String(err[6]);
|
|
|
- tooltip += "\nC " + TTR("Function:") + " " + String(err[4]);
|
|
|
+ TreeItem *r = error_tree->get_root();
|
|
|
+ if (!r) {
|
|
|
+ r = error_tree->create_item();
|
|
|
+ }
|
|
|
|
|
|
- error_list->add_item(txt, EditorNode::get_singleton()->get_gui_base()->get_icon(warning ? "Warning" : "Error", "EditorIcons"));
|
|
|
- error_list->set_item_tooltip(error_list->get_item_count() - 1, tooltip);
|
|
|
+ TreeItem *error = error_tree->create_item(r);
|
|
|
+ error->set_collapsed(true);
|
|
|
|
|
|
- int scc = p_data[1];
|
|
|
+ error->set_icon(0, get_icon(warning ? "Warning" : "Error", "EditorIcons"));
|
|
|
+ error->set_text(0, time);
|
|
|
+ error->set_text_align(0, TreeItem::ALIGN_LEFT);
|
|
|
+
|
|
|
+ error->set_text(1, txt);
|
|
|
+
|
|
|
+ String source(err[5]);
|
|
|
+ bool source_is_project_file = source.begins_with("res://");
|
|
|
+ if (source_is_project_file)
|
|
|
+ source = source.get_file();
|
|
|
+
|
|
|
+ txt = source + ":" + String(err[6]);
|
|
|
+ String method = err[4];
|
|
|
+ if (method.length() > 0)
|
|
|
+ txt += " @ " + method + "()";
|
|
|
|
|
|
- Array stack;
|
|
|
- stack.resize(scc);
|
|
|
- for (int i = 0; i < scc; i++) {
|
|
|
- stack[i] = p_data[2 + i];
|
|
|
+ TreeItem *c_info = error_tree->create_item(error);
|
|
|
+ c_info->set_text(0, "<" + TTR(source_is_project_file ? "Source" : "C Source") + ">");
|
|
|
+ c_info->set_text(1, txt);
|
|
|
+ c_info->set_text_align(0, TreeItem::ALIGN_LEFT);
|
|
|
+
|
|
|
+ if (source_is_project_file) {
|
|
|
+ Array meta;
|
|
|
+ meta.push_back(source);
|
|
|
+ meta.push_back(err[6]);
|
|
|
+ error->set_metadata(0, meta);
|
|
|
+ c_info->set_metadata(0, meta);
|
|
|
}
|
|
|
|
|
|
- error_list->set_item_metadata(error_list->get_item_count() - 1, stack);
|
|
|
+ int scc = p_data[1];
|
|
|
+
|
|
|
+ for (int i = 0; i < scc; i += 3) {
|
|
|
+ String script = p_data[2 + i];
|
|
|
+ String method = p_data[3 + i];
|
|
|
+ int line = p_data[4 + i];
|
|
|
+ TreeItem *stack_trace = error_tree->create_item(error);
|
|
|
+
|
|
|
+ Array meta;
|
|
|
+ meta.push_back(script);
|
|
|
+ meta.push_back(line);
|
|
|
+ stack_trace->set_metadata(0, meta);
|
|
|
+
|
|
|
+ if (i == 0) {
|
|
|
+ stack_trace->set_text(0, "<" + TTR("Stack Trace") + ">");
|
|
|
+ stack_trace->set_text_align(0, TreeItem::ALIGN_LEFT);
|
|
|
+ error->set_metadata(0, meta);
|
|
|
+ }
|
|
|
+ stack_trace->set_text(1, script.get_file() + ":" + itos(line) + " @ " + method + "()");
|
|
|
+ }
|
|
|
|
|
|
if (warning)
|
|
|
warning_count++;
|
|
@@ -969,8 +1007,8 @@ void ScriptEditorDebugger::_notification(int p_what) {
|
|
|
//scene_tree_refresh->set_icon( get_icon("Reload","EditorIcons"));
|
|
|
le_set->connect("pressed", this, "_live_edit_set");
|
|
|
le_clear->connect("pressed", this, "_live_edit_clear");
|
|
|
- error_list->connect("item_selected", this, "_error_selected");
|
|
|
- error_stack->connect("item_selected", this, "_error_stack_selected");
|
|
|
+ error_tree->connect("item_selected", this, "_error_selected");
|
|
|
+ error_tree->connect("item_activated", this, "_error_activated");
|
|
|
vmem_refresh->set_icon(get_icon("Reload", "EditorIcons"));
|
|
|
|
|
|
reason->add_color_override("font_color", get_color("error_color", "Editor"));
|
|
@@ -1016,19 +1054,19 @@ void ScriptEditorDebugger::_notification(int p_what) {
|
|
|
if (error_count != last_error_count || warning_count != last_warning_count) {
|
|
|
|
|
|
if (error_count == 0 && warning_count == 0) {
|
|
|
- error_split->set_name(TTR("Errors"));
|
|
|
+ error_tree->set_name(TTR("Errors"));
|
|
|
debugger_button->set_text(TTR("Debugger"));
|
|
|
debugger_button->set_icon(Ref<Texture>());
|
|
|
- tabs->set_tab_icon(error_split->get_index(), Ref<Texture>());
|
|
|
+ tabs->set_tab_icon(error_tree->get_index(), Ref<Texture>());
|
|
|
} else {
|
|
|
- error_split->set_name(TTR("Errors") + " (" + itos(error_count + warning_count) + ")");
|
|
|
+ error_tree->set_name(TTR("Errors") + " (" + itos(error_count + warning_count) + ")");
|
|
|
debugger_button->set_text(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")");
|
|
|
if (error_count == 0) {
|
|
|
debugger_button->set_icon(get_icon("Warning", "EditorIcons"));
|
|
|
- tabs->set_tab_icon(error_split->get_index(), get_icon("Warning", "EditorIcons"));
|
|
|
+ tabs->set_tab_icon(error_tree->get_index(), get_icon("Warning", "EditorIcons"));
|
|
|
} else {
|
|
|
debugger_button->set_icon(get_icon("Error", "EditorIcons"));
|
|
|
- tabs->set_tab_icon(error_split->get_index(), get_icon("Error", "EditorIcons"));
|
|
|
+ tabs->set_tab_icon(error_tree->get_index(), get_icon("Error", "EditorIcons"));
|
|
|
}
|
|
|
}
|
|
|
last_error_count = error_count;
|
|
@@ -1059,8 +1097,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
|
|
|
inspect_scene_tree->clear();
|
|
|
le_set->set_disabled(true);
|
|
|
le_clear->set_disabled(false);
|
|
|
- error_list->clear();
|
|
|
- error_stack->clear();
|
|
|
+ error_tree->clear();
|
|
|
error_count = 0;
|
|
|
warning_count = 0;
|
|
|
profiler_signature.clear();
|
|
@@ -1658,45 +1695,26 @@ void ScriptEditorDebugger::reload_scripts() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void ScriptEditorDebugger::_error_selected(int p_idx) {
|
|
|
-
|
|
|
- error_stack->clear();
|
|
|
- Array st = error_list->get_item_metadata(p_idx);
|
|
|
- for (int i = 0; i < st.size(); i += 3) {
|
|
|
-
|
|
|
- String script = st[i];
|
|
|
- String func = st[i + 1];
|
|
|
- int line = st[i + 2];
|
|
|
- Array md;
|
|
|
- md.push_back(st[i]);
|
|
|
- md.push_back(st[i + 1]);
|
|
|
- md.push_back(st[i + 2]);
|
|
|
-
|
|
|
- String str = func;
|
|
|
- String tooltip_str = TTR("Function:") + " " + func;
|
|
|
- if (script.length() > 0) {
|
|
|
- str += " in " + script.get_file();
|
|
|
- tooltip_str = TTR("File:") + " " + script + "\n" + tooltip_str;
|
|
|
- if (line > 0) {
|
|
|
- str += ":line " + itos(line);
|
|
|
- tooltip_str += "\n" + TTR("Line:") + " " + itos(line);
|
|
|
- }
|
|
|
- }
|
|
|
+void ScriptEditorDebugger::_error_activated() {
|
|
|
+ TreeItem *selected = error_tree->get_selected();
|
|
|
|
|
|
- error_stack->add_item(str);
|
|
|
- error_stack->set_item_metadata(error_stack->get_item_count() - 1, md);
|
|
|
- error_stack->set_item_tooltip(error_stack->get_item_count() - 1, tooltip_str);
|
|
|
+ TreeItem *ci = selected->get_children();
|
|
|
+ if (ci) {
|
|
|
+ selected->set_collapsed(!selected->is_collapsed());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void ScriptEditorDebugger::_error_stack_selected(int p_idx) {
|
|
|
+void ScriptEditorDebugger::_error_selected() {
|
|
|
+ TreeItem *selected = error_tree->get_selected();
|
|
|
|
|
|
- Array arr = error_stack->get_item_metadata(p_idx);
|
|
|
- if (arr.size() != 3)
|
|
|
+ Array meta = selected->get_metadata(0);
|
|
|
+
|
|
|
+ if (meta.size() == 0) {
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
- Ref<Script> s = ResourceLoader::load(arr[0]);
|
|
|
- emit_signal("goto_script_line", s, int(arr[2]) - 1);
|
|
|
+ Ref<Script> s = ResourceLoader::load(meta[0]);
|
|
|
+ emit_signal("goto_script_line", s, int(meta[1]) - 1);
|
|
|
}
|
|
|
|
|
|
void ScriptEditorDebugger::set_hide_on_stop(bool p_hide) {
|
|
@@ -1753,27 +1771,24 @@ void ScriptEditorDebugger::_clear_remote_objects() {
|
|
|
|
|
|
void ScriptEditorDebugger::_clear_errors_list() {
|
|
|
|
|
|
- error_list->clear();
|
|
|
+ error_tree->clear();
|
|
|
error_count = 0;
|
|
|
warning_count = 0;
|
|
|
_notification(NOTIFICATION_PROCESS);
|
|
|
}
|
|
|
|
|
|
// Right click on specific file(s) or folder(s).
|
|
|
-void ScriptEditorDebugger::_error_list_item_rmb_selected(int p_item, const Vector2 &p_pos) {
|
|
|
+void ScriptEditorDebugger::_error_tree_item_rmb_selected(const Vector2 &p_pos) {
|
|
|
|
|
|
item_menu->clear();
|
|
|
item_menu->set_size(Size2(1, 1));
|
|
|
|
|
|
- // Allow specific actions only on one item.
|
|
|
- bool single_item_selected = error_list->get_selected_items().size() == 1;
|
|
|
-
|
|
|
- if (single_item_selected) {
|
|
|
+ if (error_tree->is_anything_selected()) {
|
|
|
item_menu->add_icon_item(get_icon("ActionCopy", "EditorIcons"), TTR("Copy Error"), ITEM_MENU_COPY_ERROR);
|
|
|
}
|
|
|
|
|
|
if (item_menu->get_item_count() > 0) {
|
|
|
- item_menu->set_position(error_list->get_global_position() + p_pos);
|
|
|
+ item_menu->set_position(error_tree->get_global_position() + p_pos);
|
|
|
item_menu->popup();
|
|
|
}
|
|
|
}
|
|
@@ -1783,10 +1798,30 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) {
|
|
|
switch (p_option) {
|
|
|
|
|
|
case ITEM_MENU_COPY_ERROR: {
|
|
|
- String title = error_list->get_item_text(error_list->get_current());
|
|
|
- String desc = error_list->get_item_tooltip(error_list->get_current());
|
|
|
+ TreeItem *ti = error_tree->get_selected();
|
|
|
+ while (ti->get_parent() != error_tree->get_root())
|
|
|
+ ti = ti->get_parent();
|
|
|
+
|
|
|
+ String type;
|
|
|
+
|
|
|
+ if (ti->get_icon(0) == get_icon("Warning", "EditorIcons")) {
|
|
|
+ type = "W ";
|
|
|
+ } else if (ti->get_icon(0) == get_icon("Error", "EditorIcons")) {
|
|
|
+ type = "E ";
|
|
|
+ }
|
|
|
+
|
|
|
+ String text = ti->get_text(0) + " ";
|
|
|
+ int rpad_len = text.length();
|
|
|
+
|
|
|
+ text = type + text + ti->get_text(1) + "\n";
|
|
|
+ TreeItem *ci = ti->get_children();
|
|
|
+ while (ci) {
|
|
|
+ text += " " + ci->get_text(0).rpad(rpad_len) + ci->get_text(1) + "\n";
|
|
|
+ ci = ci->get_next();
|
|
|
+ }
|
|
|
+
|
|
|
+ OS::get_singleton()->set_clipboard(text);
|
|
|
|
|
|
- OS::get_singleton()->set_clipboard(title + "\n----------\n" + desc);
|
|
|
} break;
|
|
|
case ITEM_MENU_SAVE_REMOTE_NODE: {
|
|
|
|
|
@@ -1825,12 +1860,12 @@ void ScriptEditorDebugger::_bind_methods() {
|
|
|
ClassDB::bind_method(D_METHOD("_live_edit_clear"), &ScriptEditorDebugger::_live_edit_clear);
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("_error_selected"), &ScriptEditorDebugger::_error_selected);
|
|
|
- ClassDB::bind_method(D_METHOD("_error_stack_selected"), &ScriptEditorDebugger::_error_stack_selected);
|
|
|
+ ClassDB::bind_method(D_METHOD("_error_activated"), &ScriptEditorDebugger::_error_activated);
|
|
|
ClassDB::bind_method(D_METHOD("_profiler_activate"), &ScriptEditorDebugger::_profiler_activate);
|
|
|
ClassDB::bind_method(D_METHOD("_profiler_seeked"), &ScriptEditorDebugger::_profiler_seeked);
|
|
|
ClassDB::bind_method(D_METHOD("_clear_errors_list"), &ScriptEditorDebugger::_clear_errors_list);
|
|
|
|
|
|
- ClassDB::bind_method(D_METHOD("_error_list_item_rmb_selected"), &ScriptEditorDebugger::_error_list_item_rmb_selected);
|
|
|
+ ClassDB::bind_method(D_METHOD("_error_tree_item_rmb_selected"), &ScriptEditorDebugger::_error_tree_item_rmb_selected);
|
|
|
ClassDB::bind_method(D_METHOD("_item_menu_id_pressed"), &ScriptEditorDebugger::_item_menu_id_pressed);
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("_paused"), &ScriptEditorDebugger::_paused);
|
|
@@ -1964,44 +1999,35 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
|
|
|
}
|
|
|
|
|
|
{ //errors
|
|
|
-
|
|
|
- error_split = memnew(HSplitContainer);
|
|
|
- VBoxContainer *errvb = memnew(VBoxContainer);
|
|
|
HBoxContainer *errhb = memnew(HBoxContainer);
|
|
|
- errvb->set_h_size_flags(SIZE_EXPAND_FILL);
|
|
|
- Label *velb = memnew(Label(TTR("Errors:")));
|
|
|
- velb->set_h_size_flags(SIZE_EXPAND_FILL);
|
|
|
- errhb->add_child(velb);
|
|
|
+ errhb->set_name(TTR("Errors"));
|
|
|
|
|
|
- clearbutton = memnew(Button);
|
|
|
- clearbutton->set_text(TTR("Clear"));
|
|
|
- clearbutton->connect("pressed", this, "_clear_errors_list");
|
|
|
- errhb->add_child(clearbutton);
|
|
|
- errvb->add_child(errhb);
|
|
|
+ error_tree = memnew(Tree);
|
|
|
+ error_tree->set_columns(2);
|
|
|
|
|
|
- error_list = memnew(ItemList);
|
|
|
- error_list->set_v_size_flags(SIZE_EXPAND_FILL);
|
|
|
- error_list->set_h_size_flags(SIZE_EXPAND_FILL);
|
|
|
- error_list->connect("item_rmb_selected", this, "_error_list_item_rmb_selected");
|
|
|
- error_list->set_allow_rmb_select(true);
|
|
|
- error_list->set_autoscroll_to_bottom(true);
|
|
|
+ error_tree->set_column_expand(0, false);
|
|
|
+ error_tree->set_column_min_width(0, 140);
|
|
|
|
|
|
- item_menu = memnew(PopupMenu);
|
|
|
- item_menu->connect("id_pressed", this, "_item_menu_id_pressed");
|
|
|
- error_list->add_child(item_menu);
|
|
|
+ error_tree->set_column_expand(1, true);
|
|
|
|
|
|
- errvb->add_child(error_list);
|
|
|
+ error_tree->set_select_mode(Tree::SELECT_ROW);
|
|
|
+ error_tree->set_hide_root(true);
|
|
|
+ error_tree->set_h_size_flags(SIZE_EXPAND_FILL);
|
|
|
+ error_tree->set_allow_rmb_select(true);
|
|
|
+ error_tree->connect("item_rmb_selected", this, "_error_tree_item_rmb_selected");
|
|
|
+ errhb->add_child(error_tree);
|
|
|
|
|
|
- error_split->add_child(errvb);
|
|
|
+ item_menu = memnew(PopupMenu);
|
|
|
+ item_menu->connect("id_pressed", this, "_item_menu_id_pressed");
|
|
|
+ error_tree->add_child(item_menu);
|
|
|
|
|
|
- errvb = memnew(VBoxContainer);
|
|
|
- errvb->set_h_size_flags(SIZE_EXPAND_FILL);
|
|
|
- error_stack = memnew(ItemList);
|
|
|
- errvb->add_margin_child(TTR("Stack Trace (if applicable):"), error_stack, true);
|
|
|
- error_split->add_child(errvb);
|
|
|
+ clearbutton = memnew(Button);
|
|
|
+ clearbutton->set_text(TTR("Clear"));
|
|
|
+ clearbutton->set_v_size_flags(0);
|
|
|
+ clearbutton->connect("pressed", this, "_clear_errors_list");
|
|
|
+ errhb->add_child(clearbutton);
|
|
|
|
|
|
- error_split->set_name(TTR("Errors"));
|
|
|
- tabs->add_child(error_split);
|
|
|
+ tabs->add_child(errhb);
|
|
|
}
|
|
|
|
|
|
{ // remote scene tree
|