Make unsaved scripts in the script editor more user-friendly
Unsaved scripts were previously displayed with blank tabs, which are mostly a result of deleted or improperly moved scripts. This patch makes sure that those kind of scripts are displayed as "[unsaved]" now, and ensures that scripts are removed from the list while deleting scripts from the filesystem dock preventing the unsaved tabs to appear in the first place (a user is already prompted with "no undo" warning while deleting any file). A user is always prompted to save those "[unsaved]" scripts if they attempt to close them without saving in any case except as described above.
This commit is contained in:
parent
5700429e4e
commit
7247247522
@ -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);
|
||||
if (current) {
|
||||
Ref<Script> script = current->get_edited_resource();
|
||||
if (p_save) {
|
||||
// Do not try to save internal scripts
|
||||
if (!script.is_valid() || !(script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1)) {
|
||||
if (p_save && script.is_valid()) {
|
||||
// Do not try to save internal scripts, but prompt to save in-memory
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
if (script != nullptr) {
|
||||
previous_scripts.push_back(script->get_path());
|
||||
if (script.is_valid()) {
|
||||
if (!script->get_path().empty()) {
|
||||
// Only saved scripts can be restored.
|
||||
previous_scripts.push_back(script->get_path());
|
||||
}
|
||||
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("script_add_function_request", callable_mp(this, &ScriptEditor::_add_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));
|
||||
|
||||
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));
|
||||
|
||||
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]];
|
||||
}
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
@ -1850,6 +1855,12 @@ void ScriptEditor::_update_script_names() {
|
||||
if (se) {
|
||||
Ref<Texture2D> icon = se->get_theme_icon();
|
||||
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();
|
||||
String name;
|
||||
|
||||
@ -1868,7 +1879,7 @@ void ScriptEditor::_update_script_names() {
|
||||
_ScriptEditorItemData sd;
|
||||
sd.icon = icon;
|
||||
sd.name = name;
|
||||
sd.tooltip = path;
|
||||
sd.tooltip = saved ? path : TTR("Unsaved file.");
|
||||
sd.index = i;
|
||||
sd.used = used.has(se->get_edited_resource());
|
||||
sd.category = 0;
|
||||
@ -1901,6 +1912,9 @@ void ScriptEditor::_update_script_names() {
|
||||
sd.name = path;
|
||||
} break;
|
||||
}
|
||||
if (!saved) {
|
||||
sd.name = se->get_name();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (se->get_edit_menu()) {
|
||||
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));
|
||||
}
|
||||
|
||||
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() {
|
||||
save_all_scripts();
|
||||
}
|
||||
|
@ -371,6 +371,8 @@ class ScriptEditor : public PanelContainer {
|
||||
|
||||
void _save_layout();
|
||||
void _editor_settings_changed();
|
||||
void _filesystem_changed();
|
||||
void _file_removed(const String &p_file);
|
||||
void _autosave_scripts();
|
||||
void _update_autosave_timer();
|
||||
|
||||
|
@ -338,7 +338,10 @@ void ScriptTextEditor::update_settings() {
|
||||
}
|
||||
|
||||
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() {
|
||||
@ -415,6 +418,9 @@ String ScriptTextEditor::get_name() {
|
||||
if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
|
||||
name = script->get_path().get_file();
|
||||
if (is_unsaved()) {
|
||||
if (script->get_path().empty()) {
|
||||
name = TTR("[unsaved]");
|
||||
}
|
||||
name += "(*)";
|
||||
}
|
||||
} else if (script->get_name() != "") {
|
||||
|
@ -119,6 +119,9 @@ String TextEditor::get_name() {
|
||||
if (text_file->get_path().find("local://") == -1 && text_file->get_path().find("::") == -1) {
|
||||
name = text_file->get_path().get_file();
|
||||
if (is_unsaved()) {
|
||||
if (text_file->get_path().empty()) {
|
||||
name = TTR("[unsaved]");
|
||||
}
|
||||
name += "(*)";
|
||||
}
|
||||
} else if (text_file->get_name() != "") {
|
||||
@ -236,7 +239,10 @@ void TextEditor::apply_code() {
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -2551,6 +2551,9 @@ String VisualScriptEditor::get_name() {
|
||||
if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
|
||||
name = script->get_path().get_file();
|
||||
if (is_unsaved()) {
|
||||
if (script->get_path().empty()) {
|
||||
name = TTR("[unsaved]");
|
||||
}
|
||||
name += "(*)";
|
||||
}
|
||||
} else if (script->get_name() != "") {
|
||||
@ -2567,7 +2570,11 @@ Ref<Texture2D> VisualScriptEditor::get_theme_icon() {
|
||||
}
|
||||
|
||||
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() {
|
||||
|
Loading…
Reference in New Issue
Block a user