diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index 178be439c33b..6809d4ac9372 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -117,6 +117,12 @@
[b]Note:[/b] When creating custom editor UI, prefer accessing theme items directly from your GUI nodes using the [code]get_theme_*[/code] methods.
+
+
+
+ Returns the editor's [EditorUndoRedoManager].
+
+
diff --git a/doc/classes/EditorUndoRedoManager.xml b/doc/classes/EditorUndoRedoManager.xml
index 5ac0d790a237..0f8c69a1bbc9 100644
--- a/doc/classes/EditorUndoRedoManager.xml
+++ b/doc/classes/EditorUndoRedoManager.xml
@@ -68,6 +68,21 @@
Register a reference for "undo" that will be erased if the "undo" history is lost. This is useful mostly for nodes removed with the "do" call (not the "undo" call!).
+
+
+
+
+
+ Clears the given undo history. You can clear history for a specific scene, global history, or for all scenes at once if [param id] is [constant INVALID_HISTORY].
+ If [param increase_version] is [code]true[/code], the undo history version will be increased, marking it as unsaved. Useful for operations that modify the scene, but don't support undo.
+ [codeblock]
+ var scene_root = EditorInterface.get_edited_scene_root()
+ var undo_redo = EditorInterface.get_editor_undo_redo()
+ undo_redo.clear_history(undo_redo.get_object_history_id(scene_root))
+ [/codeblock]
+ [b]Note:[/b] If you want to mark an edited scene as unsaved without clearing its history, use [method EditorInterface.mark_scene_as_unsaved] instead.
+
+
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index f4403780c2b2..cd3eb7026fd6 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -6887,8 +6887,8 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
_redraw_tracks();
_update_key_edit();
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
- undo_redo->clear_history(true, undo_redo->get_history_id_for_object(animation.ptr()));
- undo_redo->clear_history(true, undo_redo->get_history_id_for_object(this));
+ undo_redo->clear_history(undo_redo->get_history_id_for_object(animation.ptr()));
+ undo_redo->clear_history(undo_redo->get_history_id_for_object(this));
} break;
case EDIT_CLEAN_UP_ANIMATION: {
@@ -7030,8 +7030,8 @@ void AnimationTrackEditor::_cleanup_animation(Ref p_animation) {
}
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
- undo_redo->clear_history(true, undo_redo->get_history_id_for_object(animation.ptr()));
- undo_redo->clear_history(true, undo_redo->get_history_id_for_object(this));
+ undo_redo->clear_history(undo_redo->get_history_id_for_object(animation.ptr()));
+ undo_redo->clear_history(undo_redo->get_history_id_for_object(this));
_update_tracks();
}
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index f01301384a24..b4265f9fc0e0 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -303,7 +303,7 @@ void EditorDebuggerNode::stop(bool p_force) {
});
_break_state_changed();
breakpoints.clear();
- EditorUndoRedoManager::get_singleton()->clear_history(false, EditorUndoRedoManager::REMOTE_HISTORY);
+ EditorUndoRedoManager::get_singleton()->clear_history(EditorUndoRedoManager::REMOTE_HISTORY, false);
set_process(false);
}
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 3b337997e066..c076c99cd3d0 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -1262,7 +1262,7 @@ void EditorAudioBuses::_load_default_layout() {
file->set_text(String(TTR("Layout:")) + " " + layout_path.get_file());
AudioServer::get_singleton()->set_bus_layout(state);
_rebuild_buses();
- EditorUndoRedoManager::get_singleton()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY);
+ EditorUndoRedoManager::get_singleton()->clear_history(EditorUndoRedoManager::GLOBAL_HISTORY);
callable_mp(this, &EditorAudioBuses::_select_layout).call_deferred();
}
@@ -1278,7 +1278,7 @@ void EditorAudioBuses::_file_dialog_callback(const String &p_string) {
file->set_text(String(TTR("Layout:")) + " " + p_string.get_file());
AudioServer::get_singleton()->set_bus_layout(state);
_rebuild_buses();
- EditorUndoRedoManager::get_singleton()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY);
+ EditorUndoRedoManager::get_singleton()->clear_history(EditorUndoRedoManager::GLOBAL_HISTORY);
callable_mp(this, &EditorAudioBuses::_select_layout).call_deferred();
} else if (file_dialog->get_file_mode() == EditorFileDialog::FILE_MODE_SAVE_FILE) {
@@ -1298,7 +1298,7 @@ void EditorAudioBuses::_file_dialog_callback(const String &p_string) {
edited_path = p_string;
file->set_text(String(TTR("Layout:")) + " " + p_string.get_file());
_rebuild_buses();
- EditorUndoRedoManager::get_singleton()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY);
+ EditorUndoRedoManager::get_singleton()->clear_history(EditorUndoRedoManager::GLOBAL_HISTORY);
callable_mp(this, &EditorAudioBuses::_select_layout).call_deferred();
}
}
@@ -1397,7 +1397,7 @@ void EditorAudioBuses::open_layout(const String &p_path) {
file->set_text(p_path.get_file());
AudioServer::get_singleton()->set_bus_layout(state);
_rebuild_buses();
- EditorUndoRedoManager::get_singleton()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY);
+ EditorUndoRedoManager::get_singleton()->clear_history(EditorUndoRedoManager::GLOBAL_HISTORY);
callable_mp(this, &EditorAudioBuses::_select_layout).call_deferred();
}
diff --git a/editor/editor_interface.cpp b/editor/editor_interface.cpp
index 46113ab2cbeb..e699b486ee8b 100644
--- a/editor/editor_interface.cpp
+++ b/editor/editor_interface.cpp
@@ -86,6 +86,10 @@ Ref EditorInterface::get_editor_settings() const {
return EditorSettings::get_singleton();
}
+EditorUndoRedoManager *EditorInterface::get_editor_undo_redo() const {
+ return EditorUndoRedoManager::get_singleton();
+}
+
TypedArray EditorInterface::_make_mesh_previews(const TypedArray &p_meshes, int p_preview_size) {
Vector[> meshes;
@@ -525,6 +529,7 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_resource_previewer"), &EditorInterface::get_resource_previewer);
ClassDB::bind_method(D_METHOD("get_selection"), &EditorInterface::get_selection);
ClassDB::bind_method(D_METHOD("get_editor_settings"), &EditorInterface::get_editor_settings);
+ ClassDB::bind_method(D_METHOD("get_editor_undo_redo"), &EditorInterface::get_editor_undo_redo);
ClassDB::bind_method(D_METHOD("make_mesh_previews", "meshes", "preview_size"), &EditorInterface::_make_mesh_previews);
diff --git a/editor/editor_interface.h b/editor/editor_interface.h
index 3ef4325780a2..2538f97c7706 100644
--- a/editor/editor_interface.h
+++ b/editor/editor_interface.h
@@ -45,6 +45,7 @@ class EditorPlugin;
class EditorResourcePreview;
class EditorSelection;
class EditorSettings;
+class EditorUndoRedoManager;
class FileSystemDock;
class Mesh;
class Node;
@@ -93,6 +94,7 @@ class EditorInterface : public Object {
EditorResourcePreview *get_resource_previewer() const;
EditorSelection *get_selection() const;
Ref get_editor_settings() const;
+ EditorUndoRedoManager *get_editor_undo_redo() const;
Vector][> make_mesh_previews(const Vector][> &p_meshes, Vector *p_transforms, int p_preview_size);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index c6144a34cb69..0aa48fe24a6f 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2961,7 +2961,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
ERR_PRINT("Failed to load scene");
}
editor_data.move_edited_scene_to_index(cur_idx);
- EditorUndoRedoManager::get_singleton()->clear_history(false, editor_data.get_current_edited_scene_history_id());
+ EditorUndoRedoManager::get_singleton()->clear_history(editor_data.get_current_edited_scene_history_id(), false);
scene_tabs->set_current_tab(cur_idx);
} break;
@@ -3963,7 +3963,7 @@ void EditorNode::_set_current_scene_nocheck(int p_idx) {
editor_folding.load_scene_folding(editor_data.get_edited_scene_root(p_idx), editor_data.get_scene_path(p_idx));
}
- EditorUndoRedoManager::get_singleton()->clear_history(false, editor_data.get_scene_history_id(p_idx));
+ EditorUndoRedoManager::get_singleton()->clear_history(editor_data.get_scene_history_id(p_idx), false);
}
Dictionary state = editor_data.restore_edited_scene_state(editor_selection, &editor_history);
@@ -4073,7 +4073,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
_set_current_scene(idx);
}
} else {
- EditorUndoRedoManager::get_singleton()->clear_history(false, editor_data.get_current_edited_scene_history_id());
+ EditorUndoRedoManager::get_singleton()->clear_history(editor_data.get_current_edited_scene_history_id(), false);
}
dependency_errors.clear();
@@ -5928,7 +5928,7 @@ void EditorNode::reload_scene(const String &p_path) {
bool is_unsaved = EditorUndoRedoManager::get_singleton()->is_history_unsaved(current_history_id);
// Scene is not open, so at it might be instantiated. We'll refresh the whole scene later.
- EditorUndoRedoManager::get_singleton()->clear_history(false, current_history_id);
+ EditorUndoRedoManager::get_singleton()->clear_history(current_history_id, false);
if (is_unsaved) {
EditorUndoRedoManager::get_singleton()->set_history_as_unsaved(current_history_id);
}
@@ -5947,7 +5947,7 @@ void EditorNode::reload_scene(const String &p_path) {
// Adjust index so tab is back a the previous position.
editor_data.move_edited_scene_to_index(scene_idx);
- EditorUndoRedoManager::get_singleton()->clear_history(false, editor_data.get_scene_history_id(scene_idx));
+ EditorUndoRedoManager::get_singleton()->clear_history(editor_data.get_scene_history_id(scene_idx), false);
// Recover the tab.
scene_tabs->set_current_tab(current_tab);
@@ -6092,7 +6092,7 @@ void EditorNode::reload_instances_with_path_in_edited_scenes() {
bool is_unsaved = EditorUndoRedoManager::get_singleton()->is_history_unsaved(current_history_id);
// Clear the history for this affected tab.
- EditorUndoRedoManager::get_singleton()->clear_history(false, current_history_id);
+ EditorUndoRedoManager::get_singleton()->clear_history(current_history_id, false);
// Update the version
editor_data.is_scene_changed(current_scene_idx);
diff --git a/editor/editor_undo_redo_manager.cpp b/editor/editor_undo_redo_manager.cpp
index 55bc198dfb5d..c0bf216634d9 100644
--- a/editor/editor_undo_redo_manager.cpp
+++ b/editor/editor_undo_redo_manager.cpp
@@ -390,7 +390,7 @@ bool EditorUndoRedoManager::has_history(int p_idx) const {
return history_map.has(p_idx);
}
-void EditorUndoRedoManager::clear_history(bool p_increase_version, int p_idx) {
+void EditorUndoRedoManager::clear_history(int p_idx, bool p_increase_version) {
if (p_idx != INVALID_HISTORY) {
History &history = get_or_create_history(p_idx);
history.undo_redo->clear_history(p_increase_version);
@@ -507,6 +507,7 @@ void EditorUndoRedoManager::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_object_history_id", "object"), &EditorUndoRedoManager::get_history_id_for_object);
ClassDB::bind_method(D_METHOD("get_history_undo_redo", "id"), &EditorUndoRedoManager::get_history_undo_redo);
+ ClassDB::bind_method(D_METHOD("clear_history", "id", "increase_version"), &EditorUndoRedoManager::clear_history, DEFVAL(INVALID_HISTORY), DEFVAL(true));
ADD_SIGNAL(MethodInfo("history_changed"));
ADD_SIGNAL(MethodInfo("version_changed"));
diff --git a/editor/editor_undo_redo_manager.h b/editor/editor_undo_redo_manager.h
index 219d5e07023e..54475c3c6cde 100644
--- a/editor/editor_undo_redo_manager.h
+++ b/editor/editor_undo_redo_manager.h
@@ -125,7 +125,7 @@ class EditorUndoRedoManager : public Object {
bool undo_history(int p_id);
bool redo();
bool redo_history(int p_id);
- void clear_history(bool p_increase_version = true, int p_idx = INVALID_HISTORY);
+ void clear_history(int p_idx = INVALID_HISTORY, bool p_increase_version = true);
void set_history_as_saved(int p_idx);
void set_history_as_unsaved(int p_idx);
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index aa075c80c33e..dc07403213cc 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -190,7 +190,7 @@ void InspectorDock::_menu_option_confirm(int p_option, bool p_confirmed) {
}
int history_id = EditorUndoRedoManager::get_singleton()->get_history_id_for_object(current);
- EditorUndoRedoManager::get_singleton()->clear_history(true, history_id);
+ EditorUndoRedoManager::get_singleton()->clear_history(history_id);
EditorNode::get_singleton()->edit_item(current, inspector);
}
]