Repository: godotengine/godot
File: editor/scene/sprite_frames_editor_plugin.cpp (C++)

Code before:

	// Copy animation to clipboard.
	Ref<ClipboardAnimation> clipboard_anim = ClipboardAnimation::from_sprite_frames(frames, edited_anim);
	EditorSettings::get_singleton()->set_resource_clipboard(clipboard_anim);

	// Remove animation with undo/redo (no confirmation dialog).
	_animation_remove_undo_redo(TTR("Cut Animation"), &clipboard_anim->animation_frames);
}

void SpriteFramesEditor::_animation_copy() {
	if (!frames->has_animation(edited_anim)) {
		return;
	}

	Ref<ClipboardAnimation> clipboard_anim = ClipboardAnimation::from_sprite_frames(frames, edited_anim);
	EditorSettings::get_singleton()->set_resource_clipboard(clipboard_anim);
}

void SpriteFramesEditor::_animation_paste() {
	Ref<ClipboardAnimation> clipboard_anim = EditorSettings::get_singleton()->get_resource_clipboard();
	if (clipboard_anim.is_null()) {
		return;
	}

	if (updating) {
		return;
	}

	String new_name = _generate_unique_animation_name(clipboard_anim->animation_name);
	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
	undo_redo->create_action(TTR("Paste Animation"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene());
	undo_redo->add_do_method(frames.ptr(), "add_animation", new_name);
	undo_redo->add_undo_method(frames.ptr(), "remove_animation", new_name);
	undo_redo->add_do_method(frames.ptr(), "set_animation_speed", new_name, clipboard_anim->animation_speed);
	undo_redo->add_do_method(frames.ptr(), "set_animation_loop", new_name, clipboard_anim->animation_loop);

	for (ClipboardSpriteFrames::Frame &frame : clipboard_anim->animation_frames) {
		undo_redo->add_do_method(frames.ptr(), "add_frame", new_name, frame.texture, frame.duration);
	}

	undo_redo->add_do_method(this, "_select_animation", new_name);
	undo_redo->add_undo_method(this, "_select_animation", edited_anim);
	undo_redo->add_do_method(this, "_update_library");
	undo_redo->add_undo_method(this, "_update_library");
	undo_redo->commit_action();
}

void SpriteFramesEditor::_animation_remove() {
	if (updating) {
		return;
	}

Review comment (performance):
I'd move this above the clipboard check. It's functionally the same and doesn't matter from a performance standpoint, but this check is simpler; there's no point in getting the `clipboard_anim` if it might not be needed.

Code after:

	// Copy animation to clipboard.
	Ref<ClipboardAnimation> clipboard_anim = ClipboardAnimation::from_sprite_frames(frames, edited_anim);
	EditorSettings::get_singleton()->set_resource_clipboard(clipboard_anim);

	// Remove animation with undo/redo (no confirmation dialog).
	_animation_remove_undo_redo(TTR("Cut Animation"), &clipboard_anim->frames);
}

void SpriteFramesEditor::_animation_copy() {
	if (!frames->has_animation(edited_anim)) {
		return;
	}

	Ref<ClipboardAnimation> clipboard_anim = ClipboardAnimation::from_sprite_frames(frames, edited_anim);
	EditorSettings::get_singleton()->set_resource_clipboard(clipboard_anim);
}

void SpriteFramesEditor::_animation_paste() {
	if (updating) {
		return;
	}

	Ref<ClipboardAnimation> clipboard_anim = EditorSettings::get_singleton()->get_resource_clipboard();
	if (clipboard_anim.is_null()) {
		return;
	}

	String new_name = _generate_unique_animation_name(clipboard_anim->name);
	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
	undo_redo->create_action(TTR("Paste Animation"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene());
	undo_redo->add_do_method(frames.ptr(), "add_animation", new_name);
	undo_redo->add_undo_method(frames.ptr(), "remove_animation", new_name);
	undo_redo->add_do_method(frames.ptr(), "set_animation_speed", new_name, clipboard_anim->speed);
	undo_redo->add_do_method(frames.ptr(), "set_animation_loop", new_name, clipboard_anim->loop);

	for (ClipboardSpriteFrames::Frame &frame : clipboard_anim->frames) {
		undo_redo->add_do_method(frames.ptr(), "add_frame", new_name, frame.texture, frame.duration);
	}

	undo_redo->add_do_method(this, "_select_animation", new_name);
	undo_redo->add_undo_method(this, "_select_animation", edited_anim);
	undo_redo->add_do_method(this, "_update_library");
	undo_redo->add_undo_method(this, "_update_library");
	undo_redo->commit_action();
}

void SpriteFramesEditor::_animation_remove() {
	if (updating) {
		return;
	}