Skip to content

Commit

Permalink
Add Save & Reload option to Reload Saved Scene
Browse files Browse the repository at this point in the history
  • Loading branch information
ryevdokimov committed Mar 1, 2025
1 parent 15ff450 commit e0fd934
Showing 1 changed file with 56 additions and 21 deletions.
77 changes: 56 additions & 21 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2714,6 +2714,26 @@ void EditorNode::_android_explore_build_templates() {
OS::get_singleton()->shell_show_in_file_manager(ProjectSettings::get_singleton()->globalize_path(export_template_manager->get_android_build_directory(android_export_preset).get_base_dir()), true);
}

static String _get_unsaved_scene_dialog_text(String p_scene_filename, uint64_t p_started_timestamp) {
String unsaved_message;

// Consider editor startup to be a point of saving, so that when you
// close and reopen the editor, you don't get an excessively long
// "modified X hours ago".
const uint64_t last_modified_seconds = Time::get_singleton()->get_unix_time_from_system() - MAX(p_started_timestamp, FileAccess::get_modified_time(p_scene_filename));
String last_modified_string;
if (last_modified_seconds < 120) {
last_modified_string = vformat(TTRN("%d second ago", "%d seconds ago", last_modified_seconds), last_modified_seconds);
} else if (last_modified_seconds < 7200) {
last_modified_string = vformat(TTRN("%d minute ago", "%d minutes ago", last_modified_seconds / 60), last_modified_seconds / 60);
} else {
last_modified_string = vformat(TTRN("%d hour ago", "%d hours ago", last_modified_seconds / 3600), last_modified_seconds / 3600);
}
unsaved_message = vformat(TTR("Scene \"%s\" has unsaved changes.\nLast saved: %s."), p_scene_filename, last_modified_string);

return unsaved_message;
}

void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if (!p_confirmed) { // FIXME: this may be a hack.
current_menu_option = (MenuOptions)p_option;
Expand Down Expand Up @@ -2947,24 +2967,29 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
break;
}

String filename = scene->get_scene_file_path();
String scene_filename = scene->get_scene_file_path();
String unsaved_message;

if (filename.is_empty()) {
if (scene_filename.is_empty()) {
show_warning(TTR("Can't reload a scene that was never saved."));
break;
}

if (unsaved_cache && !p_confirmed) {
confirmation->set_ok_button_text(TTR("Reload Saved Scene"));
confirmation->set_text(
TTR("The current scene has unsaved changes.\nReload the saved scene anyway? This action cannot be undone."));
confirmation->set_ok_button_text(TTR("Save & Reload"));
unsaved_message = _get_unsaved_scene_dialog_text(scene_filename, started_timestamp);
confirmation->set_text(unsaved_message + "\n\n" + TTR("Save before reloading the scene?"));
confirmation->popup_centered();
break;
}

int cur_idx = editor_data.get_edited_scene();
_save_scene_with_preview(scene_filename);

_remove_edited_scene();
Error err = load_scene(filename);

int cur_idx = editor_data.get_edited_scene();

Error err = load_scene(scene_filename);
if (err != OK) {
ERR_PRINT("Failed to load scene");
}
Expand Down Expand Up @@ -3436,6 +3461,25 @@ void EditorNode::_discard_changes(const String &p_str) {
}
_proceed_closing_scene_tabs();
} break;
case FILE_RELOAD_SAVED_SCENE: {
Node *scene = get_edited_scene();

String scene_filename = scene->get_scene_file_path();

int cur_idx = editor_data.get_edited_scene();

_remove_edited_scene();

Error err = load_scene(scene_filename);
if (err != OK) {
ERR_PRINT("Failed to load scene");
}
editor_data.move_edited_scene_to_index(cur_idx);
EditorUndoRedoManager::get_singleton()->clear_history(editor_data.get_current_edited_scene_history_id(), false);
scene_tabs->set_current_tab(cur_idx);

confirmation->hide();
} break;
case FILE_QUIT: {
project_run_bar->stop_playing();
_exit_editor(EXIT_SUCCESS);
Expand Down Expand Up @@ -5700,19 +5744,7 @@ void EditorNode::_scene_tab_closed(int p_tab) {
if (scene_filename.is_empty()) {
unsaved_message = TTR("This scene was never saved.");
} else {
// Consider editor startup to be a point of saving, so that when you
// close and reopen the editor, you don't get an excessively long
// "modified X hours ago".
const uint64_t last_modified_seconds = Time::get_singleton()->get_unix_time_from_system() - MAX(started_timestamp, FileAccess::get_modified_time(scene->get_scene_file_path()));
String last_modified_string;
if (last_modified_seconds < 120) {
last_modified_string = vformat(TTRN("%d second ago", "%d seconds ago", last_modified_seconds), last_modified_seconds);
} else if (last_modified_seconds < 7200) {
last_modified_string = vformat(TTRN("%d minute ago", "%d minutes ago", last_modified_seconds / 60), last_modified_seconds / 60);
} else {
last_modified_string = vformat(TTRN("%d hour ago", "%d hours ago", last_modified_seconds / 3600), last_modified_seconds / 3600);
}
unsaved_message = vformat(TTR("Scene \"%s\" has unsaved changes.\nLast saved: %s."), scene_filename, last_modified_string);
unsaved_message = _get_unsaved_scene_dialog_text(scene_filename, started_timestamp);
}
} else {
// Check if any plugin has unsaved changes in that scene.
Expand Down Expand Up @@ -7750,11 +7782,14 @@ EditorNode::EditorNode() {
gui_base->add_child(uid_upgrade_dialog);

confirmation = memnew(ConfirmationDialog);
confirmation->add_button(TTRC("Don't Save"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard");
gui_base->add_child(confirmation);
confirmation->set_min_size(Vector2(450.0 * EDSCALE, 0));
confirmation->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_menu_confirm_current));
confirmation->connect("custom_action", callable_mp(this, &EditorNode::_discard_changes));

save_confirmation = memnew(ConfirmationDialog);
save_confirmation->add_button(TTR("Don't Save"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard");
save_confirmation->add_button(TTRC("Don't Save"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard");
gui_base->add_child(save_confirmation);
save_confirmation->set_min_size(Vector2(450.0 * EDSCALE, 0));
save_confirmation->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_menu_confirm_current));
Expand Down

0 comments on commit e0fd934

Please # to comment.