- sequencer clipboard now stored globally (not in the scene, makes pasting into other scenes nicer)
- multiple pastes after copying - clear the sound handle when copying (was crashing) - allow seq freeing without a scene (assumes seq strip isnt active and sound handle isnt set) - free clipboard sequences on exit - paste sequence strips using the relative playhead location from when they were copied. TODO - check scene pointers on paste - detect overlaps after paste
This commit is contained in:
@@ -141,7 +141,7 @@ void printf_strip(struct Sequence *seq);
|
||||
void seq_free_sequence(struct Scene *scene, struct Sequence *seq);
|
||||
void seq_free_strip(struct Strip *strip);
|
||||
void seq_free_editing(struct Scene *scene);
|
||||
void seq_free_clipboard(struct Scene *scene);
|
||||
void seq_free_clipboard(void);
|
||||
struct Editing *seq_give_editing(struct Scene *scene, int alloc);
|
||||
char *give_seqname(struct Sequence *seq);
|
||||
struct ImBuf *give_ibuf_seq(struct Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size);
|
||||
@@ -230,3 +230,6 @@ struct Sequence *sequencer_add_image_strip(struct bContext *C, ListBase *seqbase
|
||||
struct Sequence *sequencer_add_sound_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
|
||||
struct Sequence *sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
|
||||
|
||||
/* copy/paste */
|
||||
extern ListBase seqbase_clipboard;
|
||||
extern int seqbase_clipboard_frame;
|
||||
|
||||
@@ -77,6 +77,8 @@ static int seqrecty= 0;
|
||||
|
||||
/* **** XXX ******** */
|
||||
|
||||
ListBase seqbase_clipboard;
|
||||
int seqbase_clipboard_frame;
|
||||
|
||||
void printf_strip(Sequence *seq)
|
||||
{
|
||||
@@ -200,23 +202,26 @@ void seq_free_strip(Strip *strip)
|
||||
|
||||
void seq_free_sequence(Scene *scene, Sequence *seq)
|
||||
{
|
||||
Editing *ed = scene->ed;
|
||||
|
||||
if(seq->strip) seq_free_strip(seq->strip);
|
||||
|
||||
if(seq->anim) IMB_free_anim(seq->anim);
|
||||
|
||||
if(seq->sound_handle)
|
||||
sound_delete_handle(scene, seq->sound_handle);
|
||||
|
||||
if (seq->type & SEQ_EFFECT) {
|
||||
struct SeqEffectHandle sh = get_sequence_effect(seq);
|
||||
|
||||
sh.free(seq);
|
||||
}
|
||||
|
||||
if (ed->act_seq==seq)
|
||||
ed->act_seq= NULL;
|
||||
/* clipboard has no scene and will never have a sound handle or be active */
|
||||
if(scene) {
|
||||
Editing *ed = scene->ed;
|
||||
|
||||
if (ed->act_seq==seq)
|
||||
ed->act_seq= NULL;
|
||||
|
||||
if(seq->sound_handle)
|
||||
sound_delete_handle(scene, seq->sound_handle);
|
||||
}
|
||||
|
||||
MEM_freeN(seq);
|
||||
}
|
||||
@@ -232,16 +237,15 @@ Editing *seq_give_editing(Scene *scene, int alloc)
|
||||
return scene->ed;
|
||||
}
|
||||
|
||||
void seq_free_clipboard(Scene *scene)
|
||||
void seq_free_clipboard(void)
|
||||
{
|
||||
Editing *ed = scene->ed;
|
||||
Sequence *seq, *nseq;
|
||||
|
||||
for(seq= ed->seqbase_clipboard.first; seq; seq= nseq) {
|
||||
for(seq= seqbase_clipboard.first; seq; seq= nseq) {
|
||||
nseq= seq->next;
|
||||
seq_free_sequence(scene, seq);
|
||||
seq_free_sequence(NULL, seq);
|
||||
}
|
||||
ed->seqbase_clipboard.first= ed->seqbase_clipboard.last= NULL;
|
||||
seqbase_clipboard.first= seqbase_clipboard.last= NULL;
|
||||
}
|
||||
|
||||
void seq_free_editing(Scene *scene)
|
||||
@@ -258,8 +262,6 @@ void seq_free_editing(Scene *scene)
|
||||
}
|
||||
SEQ_END
|
||||
|
||||
seq_free_clipboard(scene);
|
||||
|
||||
while((ms= ed->metastack.first)) {
|
||||
BLI_remlink(&ed->metastack, ms);
|
||||
MEM_freeN(ms);
|
||||
|
||||
@@ -954,7 +954,7 @@ static Sequence * deep_dupli_seq(struct Scene *scene, Sequence * seq)
|
||||
}
|
||||
|
||||
|
||||
static void recurs_dupli_seq(Scene *scene, ListBase *old, ListBase *new)
|
||||
static void recurs_dupli_seq(Scene *scene, ListBase *old, ListBase *new, int do_context)
|
||||
{
|
||||
Sequence *seq;
|
||||
Sequence *seqn = 0;
|
||||
@@ -965,15 +965,19 @@ static void recurs_dupli_seq(Scene *scene, ListBase *old, ListBase *new)
|
||||
if(seq->flag & SELECT) {
|
||||
seqn = dupli_seq(scene, seq);
|
||||
if (seqn) { /*should never fail */
|
||||
seq->flag &= SEQ_DESEL;
|
||||
seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL+SEQ_LOCK);
|
||||
if(do_context) {
|
||||
seq->flag &= SEQ_DESEL;
|
||||
seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL+SEQ_LOCK);
|
||||
}
|
||||
|
||||
BLI_addtail(new, seqn);
|
||||
if(seq->type==SEQ_META)
|
||||
recurs_dupli_seq(scene, &seq->seqbase,&seqn->seqbase);
|
||||
recurs_dupli_seq(scene, &seq->seqbase,&seqn->seqbase, do_context);
|
||||
|
||||
if (seq == last_seq) {
|
||||
active_seq_set(scene, seqn);
|
||||
if(do_context) {
|
||||
if (seq == last_seq) {
|
||||
active_seq_set(scene, seqn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1801,7 +1805,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *op)
|
||||
if(ed==NULL)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
recurs_dupli_seq(scene, ed->seqbasep, &new);
|
||||
recurs_dupli_seq(scene, ed->seqbasep, &new, TRUE);
|
||||
addlisttolist(ed->seqbasep, &new);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
|
||||
@@ -2746,19 +2750,39 @@ void SEQUENCER_OT_rendersize(wmOperatorType *ot)
|
||||
/* properties */
|
||||
}
|
||||
|
||||
static void *_copy_scene= NULL; // XXX - FIXME
|
||||
static void seq_del_sound(Scene *scene, Sequence *seq)
|
||||
{
|
||||
if(seq->type == SEQ_META) {
|
||||
Sequence *iseq;
|
||||
for(iseq= seq->seqbase.first; iseq; iseq= iseq->next) {
|
||||
seq_del_sound(scene, iseq);
|
||||
}
|
||||
}
|
||||
else if(seq->sound_handle)
|
||||
sound_delete_handle(scene, seq->sound_handle);
|
||||
|
||||
}
|
||||
|
||||
/* TODO, validate scenes */
|
||||
static int sequencer_copy_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Editing *ed= seq_give_editing(scene, FALSE);
|
||||
Sequence *seq, *seq_act;
|
||||
|
||||
if(ed==NULL)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
seq_free_clipboard(scene);
|
||||
recurs_dupli_seq(scene, ed->seqbasep, &ed->seqbase_clipboard);
|
||||
seq_free_clipboard();
|
||||
|
||||
recurs_dupli_seq(scene, ed->seqbasep, &seqbase_clipboard, FALSE);
|
||||
seqbase_clipboard_frame= scene->r.cfra;
|
||||
|
||||
/* Need to remove anything that references the current scene */
|
||||
for(seq= seqbase_clipboard.first; seq; seq= seq->next) {
|
||||
seq_del_sound(scene, seq);
|
||||
}
|
||||
|
||||
_copy_scene = scene;
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -2779,16 +2803,44 @@ void SEQUENCER_OT_copy(wmOperatorType *ot)
|
||||
/* properties */
|
||||
}
|
||||
|
||||
static void seq_offset(Sequence *seq, int ofs)
|
||||
{
|
||||
if(seq->type == SEQ_META) {
|
||||
Sequence *iseq;
|
||||
for(iseq= seq->seqbase.first; iseq; iseq= iseq->next) {
|
||||
seq_offset(iseq, ofs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
seq->start += ofs;
|
||||
}
|
||||
|
||||
calc_sequence_disp(seq);
|
||||
}
|
||||
|
||||
static int sequencer_paste_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
int retval = OPERATOR_CANCELLED;
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Editing *ed= seq_give_editing(scene, TRUE); /* create if needed */
|
||||
Editing *ed_from= seq_give_editing((Scene *)_copy_scene, TRUE); /* create if needed */
|
||||
ListBase new = {NULL, NULL};
|
||||
int ofs;
|
||||
Sequence *iseq;
|
||||
|
||||
deselect_all_seq(scene);
|
||||
ofs = scene->r.cfra - seqbase_clipboard_frame;
|
||||
|
||||
addlisttolist(ed->seqbasep, &ed_from->seqbase_clipboard);
|
||||
ed_from->seqbase_clipboard.first= ed_from->seqbase_clipboard.last= NULL; // XXX - could duplicate these to use the clip
|
||||
recurs_dupli_seq(scene, &seqbase_clipboard, &new, FALSE);
|
||||
|
||||
/* transform pasted strips before adding */
|
||||
if(ofs) {
|
||||
for(iseq= new.first; iseq; iseq= iseq->next) {
|
||||
seq_offset(iseq, ofs);
|
||||
}
|
||||
}
|
||||
|
||||
addlisttolist(ed->seqbasep, &new);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -146,6 +146,9 @@ void sequencer_keymap(wmKeyConfig *keyconf)
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_delete", XKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_delete", DELKEY, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_images_separate", YKEY, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_meta_toggle", TABKEY, KM_PRESS, 0, 0);
|
||||
|
||||
@@ -186,7 +186,6 @@ typedef struct Editing {
|
||||
ListBase *seqbasep; /* pointer to the current list of seq's being edited (can be within a meta strip) */
|
||||
ListBase seqbase; /* pointer to the top-most seq's */
|
||||
ListBase metastack;
|
||||
ListBase seqbase_clipboard; /* optionally store a copy */
|
||||
|
||||
/* Context vars, used to be static */
|
||||
Sequence *act_seq;
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_packedFile.h"
|
||||
#include "BKE_sequencer.h" /* free seq clipboard */
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
@@ -234,6 +235,8 @@ void WM_exit(bContext *C)
|
||||
|
||||
if(C && CTX_wm_manager(C))
|
||||
wm_free_reports(C); /* before free_blender! - since the ListBases get freed there */
|
||||
|
||||
seq_free_clipboard(); /* sequencer.c */
|
||||
|
||||
free_blender(); /* blender.c, does entire library and spacetypes */
|
||||
// free_matcopybuf();
|
||||
|
||||
Reference in New Issue
Block a user