diff options
-rw-r--r-- | source/blender/makesrna/intern/rna_sequencer_api.c | 13 | ||||
-rw-r--r-- | source/blender/sequencer/SEQ_edit.h | 7 | ||||
-rw-r--r-- | source/blender/sequencer/intern/strip_edit.c | 86 |
3 files changed, 77 insertions, 29 deletions
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 1fb0e502ec6..a49a404fe6c 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -81,15 +81,16 @@ static void rna_Sequence_swap_internal(Sequence *seq_self, } } -static void rna_Sequences_move_strip_to_meta(ID *id, - Sequence *seq_self, - Main *bmain, - Sequence *meta_dst) +static void rna_Sequences_move_strip_to_meta( + ID *id, Sequence *seq_self, Main *bmain, ReportList *reports, Sequence *meta_dst) { Scene *scene = (Scene *)id; + const char *error_msg; /* Move strip to meta. */ - SEQ_edit_move_strip_to_meta(scene, seq_self, meta_dst); + if (!SEQ_edit_move_strip_to_meta(scene, seq_self, meta_dst, &error_msg)) { + BKE_report(reports, RPT_ERROR, error_msg); + } /* Update depsgraph. */ DEG_relations_tag_update(bmain); @@ -651,7 +652,7 @@ void RNA_api_sequence_strip(StructRNA *srna) RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); func = RNA_def_function(srna, "move_to_meta", "rna_Sequences_move_strip_to_meta"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID | FUNC_USE_MAIN); parm = RNA_def_pointer(func, "meta_sequence", "Sequence", diff --git a/source/blender/sequencer/SEQ_edit.h b/source/blender/sequencer/SEQ_edit.h index 38ce665563c..2711e0a7ee3 100644 --- a/source/blender/sequencer/SEQ_edit.h +++ b/source/blender/sequencer/SEQ_edit.h @@ -33,9 +33,10 @@ struct Scene; struct Sequence; int SEQ_edit_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str); -int SEQ_edit_move_strip_to_meta(struct Scene *scene, - struct Sequence *src_seq, - struct Sequence *dst_seqm); +bool SEQ_edit_move_strip_to_meta(struct Scene *scene, + struct Sequence *src_seq, + struct Sequence *dst_seqm, + const char **error_str); void SEQ_edit_flag_for_removal(struct Scene *scene, struct ListBase *seqbase, struct Sequence *seq); diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index e21a25a7e4f..4a042ee2598 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -104,26 +104,6 @@ int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_ return 1; } -int SEQ_edit_move_strip_to_meta(Scene *scene, Sequence *src_seq, Sequence *dst_seqm) -{ - /* Find the appropriate seqbase */ - Editing *ed = SEQ_editing_get(scene, false); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, src_seq); - - /* Move to meta */ - BLI_remlink(seqbase, src_seq); - BLI_addtail(&dst_seqm->seqbase, src_seq); - SEQ_relations_invalidate_cache_preprocessed(scene, src_seq); - - /* Update meta */ - SEQ_time_update_sequence(scene, dst_seqm); - if (SEQ_transform_test_overlap(&dst_seqm->seqbase, src_seq)) { - SEQ_transform_seqbase_shuffle(&dst_seqm->seqbase, src_seq, scene); - } - - return 0; -} - static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute) { Sequence *seq; @@ -224,6 +204,72 @@ void SEQ_edit_remove_flagged_sequences(Scene *scene, ListBase *seqbase) } } +bool seq_exists_in_seqbase(Sequence *seq, ListBase *seqbase) +{ + LISTBASE_FOREACH (Sequence *, seq_test, seqbase) { + if (seq_test->type == SEQ_TYPE_META && seq_exists_in_seqbase(seq, &seq_test->seqbase)) { + return true; + } + if (seq_test == seq) { + return true; + } + } + return false; +} + +bool SEQ_edit_move_strip_to_meta(Scene *scene, + Sequence *src_seq, + Sequence *dst_seqm, + const char **error_str) +{ + /* Find the appropriate seqbase */ + Editing *ed = SEQ_editing_get(scene, false); + ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, src_seq); + + if (dst_seqm->type != SEQ_TYPE_META) { + *error_str = N_("Can not move strip to non-meta strip"); + return false; + } + + if (src_seq == dst_seqm) { + *error_str = N_("Strip can not be moved into itself"); + return false; + } + + if (seqbase == &dst_seqm->seqbase) { + *error_str = N_("Moved strip is already inside provided meta strip"); + return false; + } + + if (src_seq->type == SEQ_TYPE_META && seq_exists_in_seqbase(dst_seqm, &src_seq->seqbase)) { + *error_str = N_("Moved strip is parent of provided meta strip"); + return false; + } + + if (!seq_exists_in_seqbase(dst_seqm, &ed->seqbase)) { + *error_str = N_("Can not move strip to different scene"); + return false; + } + + /* Remove users of src_seq. Ideally these could be moved into meta as well, but this would be + * best to do with generalized iterator as described in D10337. */ + sequencer_flag_users_for_removal(scene, seqbase, src_seq); + SEQ_edit_remove_flagged_sequences(scene, seqbase); + + /* Move to meta. */ + BLI_remlink(seqbase, src_seq); + BLI_addtail(&dst_seqm->seqbase, src_seq); + SEQ_relations_invalidate_cache_preprocessed(scene, src_seq); + + /* Update meta. */ + SEQ_time_update_sequence(scene, dst_seqm); + if (SEQ_transform_test_overlap(&dst_seqm->seqbase, src_seq)) { + SEQ_transform_seqbase_shuffle(&dst_seqm->seqbase, src_seq, scene); + } + + return true; +} + static void seq_split_set_left_hold_offset(Sequence *seq, int timeline_frame) { /* Adjust within range of extended stillframes before strip. */ |