summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/classes/EditorPlugin.xml16
-rw-r--r--editor/editor_node.cpp26
-rw-r--r--editor/editor_node.h1
-rw-r--r--editor/editor_plugin.cpp8
-rw-r--r--editor/editor_plugin.h2
5 files changed, 52 insertions, 1 deletions
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index 957b6d8e88..8d0a13279d 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -280,6 +280,22 @@
[/codeblock]
</description>
</method>
+ <method name="_get_unsaved_status" qualifiers="virtual const">
+ <return type="String" />
+ <description>
+ Override this method to provide a custom message that lists unsaved changes. The editor will call this method on exit and display it in a confirmation dialog. Return empty string if the plugin has no unsaved changes.
+ If the user confirms saving, [method _save_external_data] will be called, before closing the editor.
+ [codeblock]
+ func _get_unsaved_status():
+ if unsaved:
+ return "Save changes in MyCustomPlugin before closing?"
+ return ""
+
+ func _save_external_data():
+ unsaved = false
+ [/codeblock]
+ </description>
+ </method>
<method name="_get_window_layout" qualifiers="virtual">
<return type="void" />
<param index="0" name="configuration" type="ConfigFile" />
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index bcf5da5e57..f304850b50 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2777,6 +2777,11 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case FILE_QUIT:
case RUN_PROJECT_MANAGER:
case RELOAD_CURRENT_PROJECT: {
+ if (p_confirmed && plugin_to_save) {
+ plugin_to_save->save_external_data();
+ p_confirmed = false;
+ }
+
if (!p_confirmed) {
bool save_each = EDITOR_GET("interface/editor/save_each_scene_on_quit");
if (_next_unsaved_scene(!save_each) == -1) {
@@ -2792,6 +2797,27 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
save_confirmation->popup_centered();
break;
}
+
+ plugin_to_save = nullptr;
+ for (int i = 0; i < editor_data.get_editor_plugin_count(); i++) {
+ const String unsaved_status = editor_data.get_editor_plugin(i)->get_unsaved_status();
+ if (!unsaved_status.is_empty()) {
+ if (p_option == RELOAD_CURRENT_PROJECT) {
+ save_confirmation->set_ok_button_text(TTR("Save & Reload"));
+ save_confirmation->set_text(RTR(unsaved_status));
+ } else {
+ save_confirmation->set_ok_button_text(TTR("Save & Quit"));
+ save_confirmation->set_text(RTR(unsaved_status));
+ }
+ save_confirmation->popup_centered();
+ plugin_to_save = editor_data.get_editor_plugin(i);
+ break;
+ }
+ }
+
+ if (plugin_to_save) {
+ break;
+ }
_discard_changes();
break;
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 65f85a76c9..6384c27c72 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -382,6 +382,7 @@ private:
AcceptDialog *save_accept = nullptr;
EditorAbout *about = nullptr;
AcceptDialog *warning = nullptr;
+ EditorPlugin *plugin_to_save = nullptr;
int overridden_default_layout = -1;
Ref<ConfigFile> default_layout;
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 5170c2fdfb..f2a8324332 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -341,7 +341,12 @@ void EditorPlugin::clear() {
GDVIRTUAL_CALL(_clear);
}
-// if editor references external resources/scenes, save them
+String EditorPlugin::get_unsaved_status() const {
+ String ret;
+ GDVIRTUAL_CALL(_get_unsaved_status, ret);
+ return ret;
+}
+
void EditorPlugin::save_external_data() {
GDVIRTUAL_CALL(_save_external_data);
}
@@ -594,6 +599,7 @@ void EditorPlugin::_bind_methods() {
GDVIRTUAL_BIND(_get_state);
GDVIRTUAL_BIND(_set_state, "state");
GDVIRTUAL_BIND(_clear);
+ GDVIRTUAL_BIND(_get_unsaved_status);
GDVIRTUAL_BIND(_save_external_data);
GDVIRTUAL_BIND(_apply_changes);
GDVIRTUAL_BIND(_get_breakpoints);
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 69789a4d4f..d74064e89c 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -88,6 +88,7 @@ protected:
GDVIRTUAL0RC(Dictionary, _get_state)
GDVIRTUAL1(_set_state, Dictionary)
GDVIRTUAL0(_clear)
+ GDVIRTUAL0RC(String, _get_unsaved_status)
GDVIRTUAL0(_save_external_data)
GDVIRTUAL0(_apply_changes)
GDVIRTUAL0RC(Vector<String>, _get_breakpoints)
@@ -175,6 +176,7 @@ public:
virtual Dictionary get_state() const; //save editor state so it can't be reloaded when reloading scene
virtual void set_state(const Dictionary &p_state); //restore editor state (likely was saved with the scene)
virtual void clear(); // clear any temporary data in the editor, reset it (likely new scene or load another scene)
+ virtual String get_unsaved_status() const;
virtual void save_external_data(); // if editor references external resources/scenes, save them
virtual void apply_changes(); // if changes are pending in editor, apply them
virtual void get_breakpoints(List<String> *p_breakpoints);