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

Code before:
	ERR_FAIL_COND(!frames->has_animation(edited_anim));

	Ref<ClipboardSpriteFrames> clipboard_frames = EditorSettings::get_singleton()->get_resource_clipboard();

	if (clipboard_frames.is_valid()) {
		_paste_frame_array(clipboard_frames);
		return;
	}

	Ref<Texture2D> texture = EditorSettings::get_singleton()->get_resource_clipboard();
	if (texture.is_valid()) {
		_paste_texture(texture);
		return;
	}
}

void SpriteFramesEditor::_paste_frame_array(const Ref<ClipboardSpriteFrames> &p_clipboard_frames) {
	if (p_clipboard_frames->frames.is_empty()) {
		return;
	}

	Ref<Texture2D> texture;
	float duration = 1.0;

	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
	undo_redo->create_action(TTR("Paste Frame(s)"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene());

	int undo_index = frames->get_frame_count(edited_anim);

	for (int index = 0; index < p_clipboard_frames->frames.size(); index++) {
		const ClipboardSpriteFrames::Frame *frame = &p_clipboard_frames->frames[index];
		texture = frame->texture;
		duration = frame->duration;

		undo_redo->add_do_method(frames.ptr(), "add_frame", edited_anim, texture, duration);
		undo_redo->add_undo_method(frames.ptr(), "remove_frame", edited_anim, undo_index);
	}

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

void SpriteFramesEditor::_paste_texture(const Ref<Texture2D> &p_texture) {
	float duration = 1.0;

	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
	undo_redo->create_action(TTR("Paste Texture"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene());

	int undo_index = frames->get_frame_count(edited_anim);


Review comment (bug):
```suggestion
	undo_redo->create_action(TTR("Paste Frame(s)"), UndoRedo::MERGE_DISABLE, frames.ptr());
```
If frames are external resource, they would be wrongly associated with the opened scene.

Code after:
	ERR_FAIL_COND(!frames->has_animation(edited_anim));

	Ref<ClipboardSpriteFrames> clipboard_frames = EditorSettings::get_singleton()->get_resource_clipboard();
	if (clipboard_frames.is_valid()) {
		_paste_frame_array(clipboard_frames);
		return;
	}

	Ref<Texture2D> texture = EditorSettings::get_singleton()->get_resource_clipboard();
	if (texture.is_valid()) {
		_paste_texture(texture);
		return;
	}
}

void SpriteFramesEditor::_paste_frame_array(const Ref<ClipboardSpriteFrames> &p_clipboard_frames) {
	if (p_clipboard_frames->frames.is_empty()) {
		return;
	}

	Ref<Texture2D> texture;
	float duration = 1.0;

	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
	undo_redo->create_action(TTR("Paste Frame(s)"), UndoRedo::MERGE_DISABLE, frames.ptr());

	int undo_index = frames->get_frame_count(edited_anim);

	for (int index = 0; index < p_clipboard_frames->frames.size(); index++) {
		const ClipboardSpriteFrames::Frame &frame = p_clipboard_frames->frames[index];
		texture = frame.texture;
		duration = frame.duration;

		undo_redo->add_do_method(frames.ptr(), "add_frame", edited_anim, texture, duration);
		undo_redo->add_undo_method(frames.ptr(), "remove_frame", edited_anim, undo_index);
	}

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

void SpriteFramesEditor::_paste_texture(const Ref<Texture2D> &p_texture) {
	float duration = 1.0;

	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
	undo_redo->create_action(TTR("Paste Texture"), UndoRedo::MERGE_DISABLE, frames.ptr());

	int undo_index = frames->get_frame_count(edited_anim);

	undo_redo->add_do_method(frames.ptr(), "add_frame", edited_anim, p_texture, duration);