Răsfoiți Sursa

Merge pull request #67963 from KoBeWi/den_of_actions

Fix nested actions in EditorUndoRedoManager
Rémi Verschelde 2 ani în urmă
părinte
comite
beed90ea6d

+ 4 - 0
core/object/undo_redo.cpp

@@ -423,6 +423,10 @@ String UndoRedo::get_current_action_name() const {
 	return actions[current_action].name;
 }
 
+int UndoRedo::get_action_level() const {
+	return action_level;
+}
+
 bool UndoRedo::has_undo() const {
 	return current_action >= 0;
 }

+ 1 - 0
core/object/undo_redo.h

@@ -120,6 +120,7 @@ public:
 	bool redo();
 	bool undo();
 	String get_current_action_name() const;
+	int get_action_level() const;
 
 	int get_history_count();
 	int get_current_action();

+ 1 - 1
editor/animation_track_editor.cpp

@@ -3613,7 +3613,7 @@ void AnimationTrackEditor::_animation_track_remove_request(int p_track, Ref<Anim
 	}
 	int idx = p_track;
 	if (idx >= 0 && idx < p_from_animation->get_track_count()) {
-		undo_redo->create_action(TTR("Remove Anim Track"));
+		undo_redo->create_action(TTR("Remove Anim Track"), UndoRedo::MERGE_DISABLE, p_from_animation.ptr());
 
 		// Remove corresponding reset tracks if they are no longer needed.
 		AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();

+ 14 - 3
editor/editor_undo_redo_manager.cpp

@@ -110,9 +110,14 @@ EditorUndoRedoManager::History &EditorUndoRedoManager::get_history_for_object(Ob
 }
 
 void EditorUndoRedoManager::create_action_for_history(const String &p_name, int p_history_id, UndoRedo::MergeMode p_mode) {
-	pending_action.action_name = p_name;
-	pending_action.timestamp = OS::get_singleton()->get_unix_time();
-	pending_action.merge_mode = p_mode;
+	if (pending_action.history_id != INVALID_HISTORY) {
+		// Nested action.
+		p_history_id = pending_action.history_id;
+	} else {
+		pending_action.action_name = p_name;
+		pending_action.timestamp = OS::get_singleton()->get_unix_time();
+		pending_action.merge_mode = p_mode;
+	}
 
 	if (p_history_id != INVALID_HISTORY) {
 		pending_action.history_id = p_history_id;
@@ -229,6 +234,12 @@ void EditorUndoRedoManager::commit_action(bool p_execute) {
 	history.undo_redo->commit_action(p_execute);
 	history.redo_stack.clear();
 
+	if (history.undo_redo->get_action_level() > 0) {
+		// Nested action.
+		is_committing = false;
+		return;
+	}
+
 	if (!history.undo_stack.is_empty()) {
 		const Action &prev_action = history.undo_stack.back()->get();
 		if (pending_action.merge_mode != UndoRedo::MERGE_DISABLE && pending_action.merge_mode == prev_action.merge_mode && pending_action.action_name == prev_action.action_name) {