diff options
author | Richard Antalik <richardantalik@gmail.com> | 2021-03-23 12:49:48 +0300 |
---|---|---|
committer | Richard Antalik <richardantalik@gmail.com> | 2021-03-23 13:23:20 +0300 |
commit | 4e0fd7fff11b76e52a5f11ba8704028c9b3c3ab0 (patch) | |
tree | 6a6da2434db1c7f2c854b001074d8b1b9351a91c /source/blender/sequencer/intern | |
parent | d3758892987d76749fdf1211ed27ff77f39b5b3b (diff) |
VSE: Sanitize move_to_meta usage
There were multiple cases that could lead to problems like moving meta
strip into itself or into it's children meta strips.
Print error string to console when invalid action is requested.
Diffstat (limited to 'source/blender/sequencer/intern')
-rw-r--r-- | source/blender/sequencer/intern/strip_edit.c | 86 |
1 files changed, 66 insertions, 20 deletions
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. */ |