Merge pull request #9304 from Noshyaar/pr-save

EditorNode: add Save/Discard/Cancel dialog
This commit is contained in:
Rémi Verschelde 2017-06-26 23:29:39 +02:00 committed by GitHub
commit 4e12bf19cc
3 changed files with 181 additions and 73 deletions

View File

@ -961,6 +961,23 @@ void EditorNode::_save_scene(String p_file, int idx) {
} }
} }
void EditorNode::_save_all_scenes() {
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
Node *scene = editor_data.get_edited_scene_root(i);
if (scene && scene->get_filename() != "") {
// save in background if in the script editor
if (i != editor_data.get_edited_scene() || _get_current_main_editor() == EDITOR_SCRIPT) {
_save_scene(scene->get_filename(), i);
} else {
_save_scene_with_preview(scene->get_filename());
}
} // else: ignore new scenes
}
_save_default_environment();
}
void EditorNode::_import_action(const String &p_action) { void EditorNode::_import_action(const String &p_action) {
#if 0 #if 0
import_confirmation->hide(); import_confirmation->hide();
@ -1117,14 +1134,26 @@ void EditorNode::_dialog_action(String p_file) {
get_undo_redo()->clear_history(); get_undo_redo()->clear_history();
} break; } break;
case FILE_CLOSE:
case FILE_CLOSE_ALL_AND_QUIT:
case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER:
case SCENE_TAB_CLOSE:
case FILE_SAVE_SCENE: case FILE_SAVE_SCENE:
case FILE_SAVE_AS_SCENE: { case FILE_SAVE_AS_SCENE: {
int scene_idx = (current_option == FILE_SAVE_SCENE || current_option == FILE_SAVE_AS_SCENE) ? -1 : tab_closing;
if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) { if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
//_save_scene(p_file); //_save_scene(p_file);
_save_default_environment(); _save_default_environment();
_save_scene_with_preview(p_file); if (scene_idx != editor_data.get_edited_scene() || _get_current_main_editor() == EDITOR_SCRIPT)
_save_scene(p_file, scene_idx);
else
_save_scene_with_preview(p_file);
if (scene_idx != -1)
_discard_changes();
} }
} break; } break;
@ -1887,42 +1916,45 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
open_request(previous_scenes.back()->get()); open_request(previous_scenes.back()->get());
} break; } break;
case FILE_CLOSE_ALL_AND_QUIT:
case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER:
case FILE_CLOSE: { case FILE_CLOSE: {
if (!p_confirmed && unsaved_cache) { if (!p_confirmed && (unsaved_cache || p_option == FILE_CLOSE_ALL_AND_QUIT || p_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER)) {
confirmation->get_ok()->set_text(TTR("Yes")); tab_closing = p_option == FILE_CLOSE ? editor_data.get_edited_scene() : _next_unsaved_scene();
//confirmation->get_cancel()->show(); String scene_filename = editor_data.get_edited_scene_root(tab_closing)->get_filename();
confirmation->set_text(TTR("Close scene? (Unsaved changes will be lost)")); save_confirmation->get_ok()->set_text(TTR("Save & Close"));
confirmation->popup_centered_minsize(); save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene_filename != "" ? scene_filename : "unsaved scene"));
save_confirmation->popup_centered_minsize();
break; break;
} }
} // fallthrough
_remove_edited_scene(); case SCENE_TAB_CLOSE:
} break;
case SCENE_TAB_CLOSE: {
_remove_scene(tab_closing);
_update_scene_tabs();
current_option = -1;
} break;
case FILE_SAVE_SCENE: { case FILE_SAVE_SCENE: {
Node *scene = editor_data.get_edited_scene_root(); int scene_idx = (p_option == FILE_SAVE_SCENE) ? -1 : tab_closing;
Node *scene = editor_data.get_edited_scene_root(scene_idx);
if (scene && scene->get_filename() != "") { if (scene && scene->get_filename() != "") {
// save in background if in the script editor // save in background if in the script editor
if (_get_current_main_editor() == EDITOR_SCRIPT) { if (scene_idx != editor_data.get_edited_scene() || _get_current_main_editor() == EDITOR_SCRIPT) {
_save_scene(scene->get_filename()); _save_scene(scene->get_filename(), scene_idx);
} else { } else {
_save_scene_with_preview(scene->get_filename()); _save_scene_with_preview(scene->get_filename());
} }
return;
}; if (scene_idx != -1)
_discard_changes();
break;
}
// fallthrough to save_as // fallthrough to save_as
}; };
case FILE_SAVE_AS_SCENE: { case FILE_SAVE_AS_SCENE: {
int scene_idx = (p_option == FILE_SAVE_SCENE || p_option == FILE_SAVE_AS_SCENE) ? -1 : tab_closing;
Node *scene = editor_data.get_edited_scene_root(); Node *scene = editor_data.get_edited_scene_root(scene_idx);
if (!scene) { if (!scene) {
@ -1958,7 +1990,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
String existing; String existing;
if (extensions.size()) { if (extensions.size()) {
String root_name(get_edited_scene()->get_name()); String root_name(scene->get_name());
existing = root_name + "." + extensions.front()->get().to_lower(); existing = root_name + "." + extensions.front()->get().to_lower();
} }
file->set_current_path(existing); file->set_current_path(existing);
@ -1969,19 +2001,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break; } break;
case FILE_SAVE_ALL_SCENES: { case FILE_SAVE_ALL_SCENES: {
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
Node *scene = editor_data.get_edited_scene_root(i);
if (scene && scene->get_filename() != "") {
// save in background if in the script editor
if (i != editor_data.get_edited_scene() || _get_current_main_editor() == EDITOR_SCRIPT) {
_save_scene(scene->get_filename(), i);
} else {
_save_scene_with_preview(scene->get_filename());
}
} // else: ignore new scenes
}
_save_default_environment(); _save_all_scenes();
} break; } break;
case FILE_SAVE_BEFORE_RUN: { case FILE_SAVE_BEFORE_RUN: {
if (!p_confirmed) { if (!p_confirmed) {
@ -2100,22 +2121,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break; } break;
case FILE_QUIT: {
if (!p_confirmed) {
confirmation->get_ok()->set_text(TTR("Quit"));
//confirmation->get_cancel()->show();
confirmation->set_text(TTR("Exit the editor?"));
confirmation->popup_centered(Size2(180, 70) * EDSCALE);
break;
}
_menu_option_confirm(RUN_STOP, true);
exiting = true;
get_tree()->quit();
} break;
case FILE_EXTERNAL_OPEN_SCENE: { case FILE_EXTERNAL_OPEN_SCENE: {
if (unsaved_cache && !p_confirmed) { if (unsaved_cache && !p_confirmed) {
@ -2444,28 +2449,53 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
project_settings->popup_project_settings(); project_settings->popup_project_settings();
} break; } break;
case FILE_QUIT:
case RUN_PROJECT_MANAGER: { case RUN_PROJECT_MANAGER: {
if (!p_confirmed) { if (!p_confirmed) {
confirmation->get_ok()->set_text(TTR("Yes")); if (_next_unsaved_scene() == -1) {
confirmation->set_text(TTR("Open Project Manager? \n(Unsaved changes will be lost)"));
confirmation->popup_centered_minsize(); bool confirm = EDITOR_DEF("interface/quit_confirmation", true);
if (confirm) {
confirmation->get_ok()->set_text(p_option == FILE_QUIT ? TTR("Quit") : TTR("Yes"));
confirmation->set_text(p_option == FILE_QUIT ? TTR("Exit the editor?") : TTR("Open Project Manager?"));
confirmation->popup_centered_minsize();
} else {
_discard_changes();
}
} else {
bool save_each = EDITOR_DEF("interface/save_each_scene_on_quit", true);
if (save_each) {
_menu_option_confirm(p_option == FILE_QUIT ? FILE_CLOSE_ALL_AND_QUIT : FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER, false);
} else {
String unsaved_scenes;
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
int current = editor_data.get_edited_scene();
bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0;
if (unsaved) {
String scene_filename = editor_data.get_edited_scene_root(i)->get_filename();
unsaved_scenes += "\n " + scene_filename;
}
}
save_confirmation->get_ok()->set_text(TTR("Save & Quit"));
save_confirmation->set_text((p_option == FILE_QUIT ? TTR("Save changes to the following scene(s) before quitting?") : TTR("Save changes the following scene(s) before opening Project Manager?")) + unsaved_scenes);
save_confirmation->popup_centered_minsize();
}
}
break; break;
} }
_menu_option_confirm(RUN_STOP, true); if (_next_unsaved_scene() != -1) {
exiting = true; _save_all_scenes();
get_tree()->quit(); }
String exec = OS::get_singleton()->get_executable_path(); _discard_changes();
List<String> args;
args.push_back("-path");
args.push_back(exec.get_base_dir());
args.push_back("-pm");
OS::ProcessID pid = 0;
Error err = OS::get_singleton()->execute(exec, args, false, &pid);
ERR_FAIL_COND(err);
} break; } break;
case RUN_FILE_SERVER: { case RUN_FILE_SERVER: {
@ -2691,6 +2721,70 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} }
} }
int EditorNode::_next_unsaved_scene() {
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
int current = editor_data.get_edited_scene();
bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0;
if (unsaved) {
return i;
}
}
return -1;
}
void EditorNode::_discard_changes(const String &p_str) {
switch (current_option) {
case FILE_CLOSE_ALL_AND_QUIT:
case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER:
case FILE_CLOSE:
case SCENE_TAB_CLOSE: {
_remove_scene(tab_closing);
_update_scene_tabs();
if (current_option == FILE_CLOSE_ALL_AND_QUIT || current_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER) {
int next_scene = _next_unsaved_scene();
if (next_scene == -1) {
current_option = current_option == FILE_CLOSE_ALL_AND_QUIT ? FILE_QUIT : RUN_PROJECT_MANAGER;
_discard_changes();
} else {
tab_closing = next_scene;
_menu_option_confirm(current_option, false);
}
} else {
current_option = -1;
save_confirmation->hide();
}
} break;
case FILE_QUIT: {
_menu_option_confirm(RUN_STOP, true);
exiting = true;
get_tree()->quit();
} break;
case RUN_PROJECT_MANAGER: {
_menu_option_confirm(RUN_STOP, true);
exiting = true;
get_tree()->quit();
String exec = OS::get_singleton()->get_executable_path();
List<String> args;
args.push_back("-path");
args.push_back(exec.get_base_dir());
args.push_back("-pm");
OS::ProcessID pid = 0;
Error err = OS::get_singleton()->execute(exec, args, false, &pid);
ERR_FAIL_COND(err);
} break;
}
}
void EditorNode::_update_debug_options() { void EditorNode::_update_debug_options() {
bool check_deploy_remote = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_deploy_remote_debug", false); bool check_deploy_remote = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_deploy_remote_debug", false);
@ -4262,19 +4356,17 @@ void EditorNode::_scene_tab_script_edited(int p_tab) {
void EditorNode::_scene_tab_closed(int p_tab) { void EditorNode::_scene_tab_closed(int p_tab) {
current_option = SCENE_TAB_CLOSE; current_option = SCENE_TAB_CLOSE;
tab_closing = p_tab; tab_closing = p_tab;
Node *scene = editor_data.get_edited_scene_root(p_tab);
bool unsaved = (p_tab == editor_data.get_edited_scene()) ? bool unsaved = (p_tab == editor_data.get_edited_scene()) ?
saved_version != editor_data.get_undo_redo().get_version() : saved_version != editor_data.get_undo_redo().get_version() :
editor_data.get_scene_version(p_tab) != 0; editor_data.get_scene_version(p_tab) != 0;
if (unsaved) { if (unsaved) {
confirmation->get_ok()->set_text(TTR("Yes")); save_confirmation->get_ok()->set_text(TTR("Save & Close"));
save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene->get_filename() != "" ? scene->get_filename() : "unsaved scene"));
//confirmation->get_cancel()->show(); save_confirmation->popup_centered_minsize();
confirmation->set_text(TTR("Close scene? (Unsaved changes will be lost)"));
confirmation->popup_centered_minsize();
} else { } else {
_remove_scene(p_tab); _discard_changes();
_update_scene_tabs();
} }
} }
@ -4892,6 +4984,7 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("_scene_tab_script_edited", &EditorNode::_scene_tab_script_edited); ClassDB::bind_method("_scene_tab_script_edited", &EditorNode::_scene_tab_script_edited);
ClassDB::bind_method("_set_main_scene_state", &EditorNode::_set_main_scene_state); ClassDB::bind_method("_set_main_scene_state", &EditorNode::_set_main_scene_state);
ClassDB::bind_method("_update_scene_tabs", &EditorNode::_update_scene_tabs); ClassDB::bind_method("_update_scene_tabs", &EditorNode::_update_scene_tabs);
ClassDB::bind_method("_discard_changes", &EditorNode::_discard_changes);
ClassDB::bind_method("_prepare_history", &EditorNode::_prepare_history); ClassDB::bind_method("_prepare_history", &EditorNode::_prepare_history);
ClassDB::bind_method("_select_history", &EditorNode::_select_history); ClassDB::bind_method("_select_history", &EditorNode::_select_history);
@ -5891,6 +5984,12 @@ EditorNode::EditorNode() {
gui_base->add_child(confirmation); gui_base->add_child(confirmation);
confirmation->connect("confirmed", this, "_menu_confirm_current"); confirmation->connect("confirmed", this, "_menu_confirm_current");
save_confirmation = memnew(ConfirmationDialog);
save_confirmation->add_button(TTR("Don't Save"), OS::get_singleton()->get_swap_ok_cancel(), "discard");
gui_base->add_child(save_confirmation);
save_confirmation->connect("confirmed", this, "_menu_confirm_current");
save_confirmation->connect("custom_action", this, "_discard_changes");
accept = memnew(AcceptDialog); accept = memnew(AcceptDialog);
gui_base->add_child(accept); gui_base->add_child(accept);
accept->connect("confirmed", this, "_menu_confirm_current"); accept->connect("confirmed", this, "_menu_confirm_current");

View File

@ -140,6 +140,8 @@ private:
FILE_RUN_SCRIPT, FILE_RUN_SCRIPT,
FILE_OPEN_PREV, FILE_OPEN_PREV,
FILE_CLOSE, FILE_CLOSE,
FILE_CLOSE_ALL_AND_QUIT,
FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER,
FILE_QUIT, FILE_QUIT,
FILE_EXTERNAL_OPEN_SCENE, FILE_EXTERNAL_OPEN_SCENE,
EDIT_UNDO, EDIT_UNDO,
@ -296,6 +298,7 @@ private:
//CallDialog *call_dialog; //CallDialog *call_dialog;
ConfirmationDialog *confirmation; ConfirmationDialog *confirmation;
ConfirmationDialog *save_confirmation;
ConfirmationDialog *import_confirmation; ConfirmationDialog *import_confirmation;
ConfirmationDialog *open_recent_confirmation; ConfirmationDialog *open_recent_confirmation;
ConfirmationDialog *pick_main_scene; ConfirmationDialog *pick_main_scene;
@ -465,6 +468,9 @@ private:
void _vp_resized(); void _vp_resized();
void _save_scene(String p_file, int idx = -1); void _save_scene(String p_file, int idx = -1);
void _save_all_scenes();
int _next_unsaved_scene();
void _discard_changes(const String &p_str = String());
void _instance_request(const Vector<String> &p_files); void _instance_request(const Vector<String> &p_files);

View File

@ -517,6 +517,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("interface/separate_distraction_mode", false); set("interface/separate_distraction_mode", false);
set("interface/save_each_scene_on_quit", true); // Regression
set("interface/quit_confirmation", true);
set("interface/theme/preset", 0); set("interface/theme/preset", 0);
hints["interface/theme/preset"] = PropertyInfo(Variant::INT, "interface/theme/preset", PROPERTY_HINT_ENUM, "Default,Grey,Godot 2,Arc,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); hints["interface/theme/preset"] = PropertyInfo(Variant::INT, "interface/theme/preset", PROPERTY_HINT_ENUM, "Default,Grey,Godot 2,Arc,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
set("interface/theme/base_color", Color::html("#273241")); set("interface/theme/base_color", Color::html("#273241"));