This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/sequencer/intern/clipboard.c
Sebastian Parborg f49d438ced Cleanup and remove SEQ_ALL_BEGIN macro
We now use a for_each function with callback to iterate through all sequences in the scene.

This has the benefit that we now only loop over the sequences in the scene once.
Before we would loop over them twice and allocate memory to store temporary data.

The allocation of temporary data lead to unintentional memory leaks if the code used returns to exit out of the iteration loop.
The new for_each callback method doesn't allocate any temporary data and only iterates though all sequences once.

Reviewed By: Richard Antalik, Bastien Montagne

Differential Revision: http://developer.blender.org/D12278
2021-08-25 17:30:39 +02:00

208 lines
6.1 KiB
C

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* - Blender Foundation, 2003-2009
* - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
*/
/** \file
* \ingroup bke
*/
#include <string.h>
#include "MEM_guardedalloc.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BKE_main.h"
#include "BKE_movieclip.h"
#include "BKE_scene.h"
#include "BKE_sound.h"
#include "SEQ_clipboard.h"
#include "SEQ_select.h"
#include "sequencer.h"
#ifdef WITH_AUDASPACE
# include <AUD_Special.h>
#endif
/* -------------------------------------------------------------------- */
/* Manage pointers in the clipboard.
* note that these pointers should _never_ be access in the sequencer,
* they are only for storage while in the clipboard
* notice 'newid' is used for temp pointer storage here, validate on access (this is safe usage,
* since those data-blocks are fully out of Main lists).
*/
ListBase seqbase_clipboard;
int seqbase_clipboard_frame;
static char seq_clipboard_active_seq_name[SEQ_NAME_MAXSTR];
void seq_clipboard_pointers_free(struct ListBase *seqbase);
void SEQ_clipboard_free(void)
{
Sequence *seq, *nseq;
seq_clipboard_pointers_free(&seqbase_clipboard);
for (seq = seqbase_clipboard.first; seq; seq = nseq) {
nseq = seq->next;
seq_free_sequence_recurse(NULL, seq, false, true);
}
BLI_listbase_clear(&seqbase_clipboard);
}
#define ID_PT (*id_pt)
static void seqclipboard_ptr_free(Main *UNUSED(bmain), ID **id_pt)
{
if (ID_PT) {
BLI_assert(ID_PT->newid != NULL);
MEM_freeN(ID_PT);
ID_PT = NULL;
}
}
static void seqclipboard_ptr_store(Main *UNUSED(bmain), ID **id_pt)
{
if (ID_PT) {
ID *id_prev = ID_PT;
ID_PT = MEM_dupallocN(ID_PT);
ID_PT->newid = id_prev;
}
}
static void seqclipboard_ptr_restore(Main *bmain, ID **id_pt)
{
if (ID_PT) {
const ListBase *lb = which_libbase(bmain, GS(ID_PT->name));
void *id_restore;
BLI_assert(ID_PT->newid != NULL);
if (BLI_findindex(lb, (ID_PT)->newid) != -1) {
/* the pointer is still valid */
id_restore = (ID_PT)->newid;
}
else {
/* The pointer of the same name still exists. */
id_restore = BLI_findstring(lb, (ID_PT)->name + 2, offsetof(ID, name) + 2);
}
if (id_restore == NULL) {
/* check for a data with the same filename */
switch (GS(ID_PT->name)) {
case ID_SO: {
id_restore = BLI_findstring(lb, ((bSound *)ID_PT)->filepath, offsetof(bSound, filepath));
if (id_restore == NULL) {
id_restore = BKE_sound_new_file(bmain, ((bSound *)ID_PT)->filepath);
(ID_PT)->newid = id_restore; /* reuse next time */
}
break;
}
case ID_MC: {
id_restore = BLI_findstring(
lb, ((MovieClip *)ID_PT)->filepath, offsetof(MovieClip, filepath));
if (id_restore == NULL) {
id_restore = BKE_movieclip_file_add(bmain, ((MovieClip *)ID_PT)->filepath);
(ID_PT)->newid = id_restore; /* reuse next time */
}
break;
}
default:
break;
}
}
/* Replace with pointer to actual data-block. */
seqclipboard_ptr_free(bmain, id_pt);
ID_PT = id_restore;
}
}
#undef ID_PT
static void sequence_clipboard_pointers(Main *bmain,
Sequence *seq,
void (*callback)(Main *, ID **))
{
callback(bmain, (ID **)&seq->scene);
callback(bmain, (ID **)&seq->scene_camera);
callback(bmain, (ID **)&seq->clip);
callback(bmain, (ID **)&seq->mask);
callback(bmain, (ID **)&seq->sound);
if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
TextVars *text_data = seq->effectdata;
callback(bmain, (ID **)&text_data->text_font);
}
}
/* recursive versions of functions above */
void seq_clipboard_pointers_free(ListBase *seqbase)
{
Sequence *seq;
for (seq = seqbase->first; seq; seq = seq->next) {
sequence_clipboard_pointers(NULL, seq, seqclipboard_ptr_free);
seq_clipboard_pointers_free(&seq->seqbase);
}
}
void SEQ_clipboard_pointers_store(Main *bmain, ListBase *seqbase)
{
Sequence *seq;
for (seq = seqbase->first; seq; seq = seq->next) {
sequence_clipboard_pointers(bmain, seq, seqclipboard_ptr_store);
SEQ_clipboard_pointers_store(bmain, &seq->seqbase);
}
}
void SEQ_clipboard_pointers_restore(ListBase *seqbase, Main *bmain)
{
Sequence *seq;
for (seq = seqbase->first; seq; seq = seq->next) {
sequence_clipboard_pointers(bmain, seq, seqclipboard_ptr_restore);
SEQ_clipboard_pointers_restore(&seq->seqbase, bmain);
}
}
void SEQ_clipboard_active_seq_name_store(Scene *scene)
{
Sequence *active_seq = SEQ_select_active_get(scene);
if (active_seq != NULL) {
STRNCPY(seq_clipboard_active_seq_name, active_seq->name);
}
else {
seq_clipboard_active_seq_name[0] = '\0';
}
}
/**
* Check if strip was active when it was copied. User should restrict this check to pasted strips
* before ensuring original name, because strip name comparison is used to check.
*
* \param pasted_seq: Strip that is pasted(duplicated) from clipboard
* \return true if strip was active, false otherwise
*/
bool SEQ_clipboard_pasted_seq_was_active(Sequence *pasted_seq)
{
return STREQ(pasted_seq->name, seq_clipboard_active_seq_name);
}