Merge pull request #40647 from Xrayez/blank-tabs-fix

Make unsaved scripts in the script editor more user-friendly
This commit is contained in:
Rémi Verschelde 2020-07-26 17:11:31 +02:00 committed by GitHub
commit c75f4c06f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 65 additions and 10 deletions

View File

@ -699,15 +699,18 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
ScriptEditorBase *current = Object::cast_to<ScriptEditorBase>(tselected); ScriptEditorBase *current = Object::cast_to<ScriptEditorBase>(tselected);
if (current) { if (current) {
Ref<Script> script = current->get_edited_resource(); Ref<Script> script = current->get_edited_resource();
if (p_save) { if (p_save && script.is_valid()) {
// Do not try to save internal scripts // Do not try to save internal scripts, but prompt to save in-memory
if (!script.is_valid() || !(script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1)) { // scripts which are not saved to disk yet (have empty path).
if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
_menu_option(FILE_SAVE); _menu_option(FILE_SAVE);
} }
} }
if (script.is_valid()) {
if (script != nullptr) { if (!script->get_path().empty()) {
previous_scripts.push_back(script->get_path()); // Only saved scripts can be restored.
previous_scripts.push_back(script->get_path());
}
notify_script_close(script); notify_script_close(script);
} }
} }
@ -1471,6 +1474,7 @@ void ScriptEditor::_notification(int p_what) {
editor->connect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop)); editor->connect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
editor->connect("script_add_function_request", callable_mp(this, &ScriptEditor::_add_callback)); editor->connect("script_add_function_request", callable_mp(this, &ScriptEditor::_add_callback));
editor->connect("resource_saved", callable_mp(this, &ScriptEditor::_res_saved_callback)); editor->connect("resource_saved", callable_mp(this, &ScriptEditor::_res_saved_callback));
editor->get_filesystem_dock()->connect("file_removed", callable_mp(this, &ScriptEditor::_file_removed));
script_list->connect("item_selected", callable_mp(this, &ScriptEditor::_script_selected)); script_list->connect("item_selected", callable_mp(this, &ScriptEditor::_script_selected));
members_overview->connect("item_selected", callable_mp(this, &ScriptEditor::_members_overview_selected)); members_overview->connect("item_selected", callable_mp(this, &ScriptEditor::_members_overview_selected));
@ -1478,6 +1482,7 @@ void ScriptEditor::_notification(int p_what) {
script_split->connect("dragged", callable_mp(this, &ScriptEditor::_script_split_dragged)); script_split->connect("dragged", callable_mp(this, &ScriptEditor::_script_split_dragged));
EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &ScriptEditor::_editor_settings_changed)); EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &ScriptEditor::_editor_settings_changed));
EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &ScriptEditor::_filesystem_changed));
[[fallthrough]]; [[fallthrough]];
} }
case NOTIFICATION_THEME_CHANGED: { case NOTIFICATION_THEME_CHANGED: {
@ -1850,6 +1855,12 @@ void ScriptEditor::_update_script_names() {
if (se) { if (se) {
Ref<Texture2D> icon = se->get_theme_icon(); Ref<Texture2D> icon = se->get_theme_icon();
String path = se->get_edited_resource()->get_path(); String path = se->get_edited_resource()->get_path();
bool saved = !path.empty();
if (saved) {
// The script might be deleted, moved, or renamed, so make sure
// to update original path to previously edited resource.
se->set_meta("_edit_res_path", path);
}
bool built_in = !path.is_resource_file(); bool built_in = !path.is_resource_file();
String name; String name;
@ -1868,7 +1879,7 @@ void ScriptEditor::_update_script_names() {
_ScriptEditorItemData sd; _ScriptEditorItemData sd;
sd.icon = icon; sd.icon = icon;
sd.name = name; sd.name = name;
sd.tooltip = path; sd.tooltip = saved ? path : TTR("Unsaved file.");
sd.index = i; sd.index = i;
sd.used = used.has(se->get_edited_resource()); sd.used = used.has(se->get_edited_resource());
sd.category = 0; sd.category = 0;
@ -1901,6 +1912,9 @@ void ScriptEditor::_update_script_names() {
sd.name = path; sd.name = path;
} break; } break;
} }
if (!saved) {
sd.name = se->get_name();
}
sedata.push_back(sd); sedata.push_back(sd);
} }
@ -2222,6 +2236,9 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
se->enable_editor(); se->enable_editor();
} }
// If we delete a script within the filesystem, the original resource path
// is lost, so keep it as metadata to figure out the exact tab to delete.
se->set_meta("_edit_res_path", p_resource->get_path());
se->set_tooltip_request_func("_get_debug_tooltip", this); se->set_tooltip_request_func("_get_debug_tooltip", this);
if (se->get_edit_menu()) { if (se->get_edit_menu()) {
se->get_edit_menu()->hide(); se->get_edit_menu()->hide();
@ -2396,6 +2413,23 @@ void ScriptEditor::_editor_settings_changed() {
ScriptServer::set_reload_scripts_on_save(EDITOR_DEF("text_editor/files/auto_reload_and_parse_scripts_on_save", true)); ScriptServer::set_reload_scripts_on_save(EDITOR_DEF("text_editor/files/auto_reload_and_parse_scripts_on_save", true));
} }
void ScriptEditor::_filesystem_changed() {
_update_script_names();
}
void ScriptEditor::_file_removed(const String &p_removed_file) {
for (int i = 0; i < tab_container->get_child_count(); i++) {
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (!se) {
continue;
}
if (se->get_meta("_edit_res_path") == p_removed_file) {
// The script is deleted with no undo, so just close the tab.
_close_tab(i, false, false);
}
}
}
void ScriptEditor::_autosave_scripts() { void ScriptEditor::_autosave_scripts() {
save_all_scripts(); save_all_scripts();
} }

View File

@ -371,6 +371,8 @@ class ScriptEditor : public PanelContainer {
void _save_layout(); void _save_layout();
void _editor_settings_changed(); void _editor_settings_changed();
void _filesystem_changed();
void _file_removed(const String &p_file);
void _autosave_scripts(); void _autosave_scripts();
void _update_autosave_timer(); void _update_autosave_timer();

View File

@ -338,7 +338,10 @@ void ScriptTextEditor::update_settings() {
} }
bool ScriptTextEditor::is_unsaved() { bool ScriptTextEditor::is_unsaved() {
return code_editor->get_text_edit()->get_version() != code_editor->get_text_edit()->get_saved_version(); const bool unsaved =
code_editor->get_text_edit()->get_version() != code_editor->get_text_edit()->get_saved_version() ||
script->get_path().empty(); // In memory.
return unsaved;
} }
Variant ScriptTextEditor::get_edit_state() { Variant ScriptTextEditor::get_edit_state() {
@ -415,6 +418,9 @@ String ScriptTextEditor::get_name() {
if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) { if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
name = script->get_path().get_file(); name = script->get_path().get_file();
if (is_unsaved()) { if (is_unsaved()) {
if (script->get_path().empty()) {
name = TTR("[unsaved]");
}
name += "(*)"; name += "(*)";
} }
} else if (script->get_name() != "") { } else if (script->get_name() != "") {

View File

@ -119,6 +119,9 @@ String TextEditor::get_name() {
if (text_file->get_path().find("local://") == -1 && text_file->get_path().find("::") == -1) { if (text_file->get_path().find("local://") == -1 && text_file->get_path().find("::") == -1) {
name = text_file->get_path().get_file(); name = text_file->get_path().get_file();
if (is_unsaved()) { if (is_unsaved()) {
if (text_file->get_path().empty()) {
name = TTR("[unsaved]");
}
name += "(*)"; name += "(*)";
} }
} else if (text_file->get_name() != "") { } else if (text_file->get_name() != "") {
@ -236,7 +239,10 @@ void TextEditor::apply_code() {
} }
bool TextEditor::is_unsaved() { bool TextEditor::is_unsaved() {
return code_editor->get_text_edit()->get_version() != code_editor->get_text_edit()->get_saved_version(); const bool unsaved =
code_editor->get_text_edit()->get_version() != code_editor->get_text_edit()->get_saved_version() ||
text_file->get_path().empty(); // In memory.
return unsaved;
} }
Variant TextEditor::get_edit_state() { Variant TextEditor::get_edit_state() {

View File

@ -2551,6 +2551,9 @@ String VisualScriptEditor::get_name() {
if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) { if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
name = script->get_path().get_file(); name = script->get_path().get_file();
if (is_unsaved()) { if (is_unsaved()) {
if (script->get_path().empty()) {
name = TTR("[unsaved]");
}
name += "(*)"; name += "(*)";
} }
} else if (script->get_name() != "") { } else if (script->get_name() != "") {
@ -2567,7 +2570,11 @@ Ref<Texture2D> VisualScriptEditor::get_theme_icon() {
} }
bool VisualScriptEditor::is_unsaved() { bool VisualScriptEditor::is_unsaved() {
return script->is_edited() || script->are_subnodes_edited(); bool unsaved =
script->is_edited() ||
script->are_subnodes_edited() ||
script->get_path().empty(); // In memory.
return unsaved;
} }
Variant VisualScriptEditor::get_edit_state() { Variant VisualScriptEditor::get_edit_state() {