From 113d556295a84603b95e5bc318e2cb28a27097ed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Sep 2011 14:12:27 +0000 Subject: patch [#28571] from Bastien Montagne (mont29) Only applied Sequencer Select Grouped functionality - similar to the one in object mode, select strips based on type, time, data etc. --- .../editors/space_sequencer/sequencer_intern.h | 2 +- .../editors/space_sequencer/sequencer_ops.c | 5 +- .../editors/space_sequencer/sequencer_select.c | 266 +++++++++++++++++++++ 3 files changed, 271 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 89e9a22c9a1..a0999c9a03b 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -134,7 +134,7 @@ void SEQUENCER_OT_select_handles(struct wmOperatorType *ot); void SEQUENCER_OT_select_active_side(struct wmOperatorType *ot); void SEQUENCER_OT_select_border(struct wmOperatorType *ot); void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot); - +void SEQUENCER_OT_select_grouped(struct wmOperatorType *ot); /* sequencer_select.c */ void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index ecc8fe7f967..b53284136de 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -103,7 +103,8 @@ void sequencer_operatortypes(void) WM_operatortype_append(SEQUENCER_OT_select_handles); WM_operatortype_append(SEQUENCER_OT_select_active_side); WM_operatortype_append(SEQUENCER_OT_select_border); - + WM_operatortype_append(SEQUENCER_OT_select_grouped); + /* sequencer_add.c */ WM_operatortype_append(SEQUENCER_OT_scene_strip_add); WM_operatortype_append(SEQUENCER_OT_movie_strip_add); @@ -247,6 +248,8 @@ void sequencer_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "SEQUENCER_OT_select_border", BKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "SEQUENCER_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_menu(keymap, "SEQUENCER_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_menu(keymap, "SEQUENCER_MT_change", CKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 3ea27899128..f1c1e21758d 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -47,6 +47,7 @@ #include "DNA_scene_types.h" #include "BKE_context.h" +#include "BKE_report.h" #include "BKE_sequencer.h" #include "WM_api.h" @@ -882,3 +883,268 @@ void SEQUENCER_OT_select_border(wmOperatorType *ot) /* rna */ WM_operator_properties_gesture_border(ot, FALSE); } + +/* ****** Selected Grouped ****** */ + +static EnumPropertyItem sequencer_prop_select_grouped_types[] = { + {1, "TYPE", 0, "Type", "Shared strip type"}, + {2, "TYPE_BASIC", 0, "Global Type", "All strips of same basic type (Graphical or Sound)"}, + {3, "TYPE_EFFECT", 0, "Effect Type", "Shared strip effect type (if active strip is not an effect one, select all non-effect strips)"}, + {4, "DATA", 0, "Data", "Shared data (scene, image, sound, etc.)"}, + {5, "EFFECT", 0, "Effect", "Shared effects"}, + {6, "EFFECT_LINK", 0, "Effect/Linked", "Other strips affected by the active one (sharing some time, and below or effect-assigned)"}, + {7, "OVERLAP", 0, "Overlap", "Overlapping time"}, + {0, NULL, 0, NULL, NULL} +}; + +#define SEQ_IS_SOUND(_seq) ((_seq->type & SEQ_SOUND) && !(_seq->type & SEQ_EFFECT)) + +#define SEQ_IS_EFFECT(_seq) (_seq->type & SEQ_EFFECT) + +#define SEQ_USE_DATA(_seq) (_seq->type == SEQ_SCENE || SEQ_HAS_PATH(_seq)) + +static short select_grouped_type(Editing *ed, Sequence *actseq) +{ + Sequence *seq; + short changed = FALSE; + + SEQP_BEGIN(ed, seq) { + if (seq->type == actseq->type) { + seq->flag |= SELECT; + changed = TRUE; + } + } + SEQ_END; + + return changed; +} + +static short select_grouped_type_basic(Editing *ed, Sequence *actseq) +{ + Sequence *seq; + short changed = FALSE; + short is_sound = SEQ_IS_SOUND(actseq); + + SEQP_BEGIN(ed, seq) { + if (is_sound ? SEQ_IS_SOUND(seq) : !SEQ_IS_SOUND(seq)) { + seq->flag |= SELECT; + changed = TRUE; + } + } + SEQ_END; + + return changed; +} + +static short select_grouped_type_effect(Editing *ed, Sequence *actseq) +{ + Sequence *seq; + short changed = FALSE; + short is_effect = SEQ_IS_EFFECT(actseq); + + SEQP_BEGIN(ed, seq) { + if (is_effect ? SEQ_IS_EFFECT(seq) : !SEQ_IS_EFFECT(seq)) { + seq->flag |= SELECT; + changed = TRUE; + } + } + SEQ_END; + + return changed; +} + +static short select_grouped_data(Editing *ed, Sequence *actseq) +{ + Sequence *seq; + short changed = FALSE; + Scene *sce = actseq->scene; + char *dir = actseq->strip ? actseq->strip->dir : NULL; + + if (!SEQ_USE_DATA(actseq)) + return changed; + + if (SEQ_HAS_PATH(actseq) && dir) { + SEQP_BEGIN(ed, seq) { + if (SEQ_HAS_PATH(seq) && seq->strip && strcmp(seq->strip->dir, dir) == 0) { + seq->flag |= SELECT; + changed = TRUE; + } + } + SEQ_END; + } + else { + SEQP_BEGIN(ed, seq) { + if (seq->type == SEQ_SCENE && seq->scene == sce) { + seq->flag |= SELECT; + changed = TRUE; + } + } + SEQ_END; + } + + return changed; +} + +static short select_grouped_effect(Editing *ed, Sequence *actseq) +{ + Sequence *seq; + short changed = FALSE; + short effects[SEQ_EFFECT_MAX+1]; + int i; + + for (i = 0; i <= SEQ_EFFECT_MAX; i++) + effects[i] = FALSE; + + SEQP_BEGIN(ed, seq) { + if (ELEM3(actseq, seq->seq1, seq->seq2, seq->seq3)) { + effects[seq->type] = TRUE; + } + } + SEQ_END; + + SEQP_BEGIN(ed, seq) { + if (effects[seq->type]) { + if(seq->seq1) seq->seq1->flag |= SELECT; + if(seq->seq2) seq->seq2->flag |= SELECT; + if(seq->seq3) seq->seq3->flag |= SELECT; + changed = TRUE; + } + } + SEQ_END; + + return changed; +} + +static short select_grouped_time_overlap(Editing *ed, Sequence *actseq) +{ + Sequence *seq; + short changed = FALSE; + + SEQP_BEGIN(ed, seq) { + if (!((seq->startdisp >= actseq->enddisp) || (seq->enddisp < actseq->startdisp))) { + seq->flag |= SELECT; + changed = TRUE; + } + } + SEQ_END; + + return changed; +} + +static short select_grouped_effect_link(Editing *ed, Sequence *actseq) +{ + Sequence *seq; + short changed = FALSE; + short is_audio = ((actseq->type == SEQ_META) || SEQ_IS_SOUND(actseq)); + int startdisp = actseq->startdisp; + int enddisp = actseq->enddisp; + int machine = actseq->machine; + SeqIterator iter; + + SEQP_BEGIN(ed, seq) { + seq->tmp= NULL; + } + SEQ_END; + + seq->tmp= SET_INT_IN_POINTER(TRUE); + + for(seq_begin(ed, &iter, 1); iter.valid; seq_next(&iter)) { + seq = iter.seq; + + /* Ignore all seqs already selected! */ + /* Ignore all seqs not sharing some time with active one. */ + /* Ignore all seqs of incompatible types (audio vs video). */ + if ((seq->flag & SELECT) || (seq->startdisp >= enddisp) || (seq->enddisp < startdisp) + || (!is_audio && SEQ_IS_SOUND(seq)) + || (is_audio && !((seq->type == SEQ_META) || SEQ_IS_SOUND(seq)))) + continue; + + /* If the seq is an effect one, we need extra cheking! */ + if (SEQ_IS_EFFECT(seq) && ((seq->seq1 && seq->seq1->tmp) || + (seq->seq2 && seq->seq2->tmp) || + (seq->seq3 && seq->seq3->tmp))) + { + if (startdisp > seq->startdisp) startdisp = seq->startdisp; + if (enddisp < seq->enddisp) enddisp = seq->enddisp; + if (machine < seq->machine) machine = seq->machine; + + seq->tmp= SET_INT_IN_POINTER(TRUE); + + seq->flag |= SELECT; + changed = TRUE; + + /* Unfortunately, we must restart checks from the begining. */ + seq_end(&iter); + seq_begin(ed, &iter, 1); + } + + /* Video strips bellow active one, or any strip for audio (order do no matters here!). */ + else if (seq->machine < machine || is_audio) { + seq->flag |= SELECT; + changed = TRUE; + } + } + seq_end(&iter); + + return changed; +} + +static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Editing *ed = seq_give_editing(scene, 0); + Sequence *seq, *actseq = seq_active_get(scene); + int type = RNA_enum_get(op->ptr, "type"); + short changed = 0, extend; + + extend = RNA_boolean_get(op->ptr, "extend"); + + if (actseq == NULL) { + BKE_report(op->reports, RPT_ERROR, "No Active Sequence!"); + return OPERATOR_CANCELLED; + } + + if (extend == 0) { + SEQP_BEGIN(ed, seq) { + seq->flag &= ~SELECT; + changed = TRUE; + } + SEQ_END; + } + + if(type==1) changed |= select_grouped_type(ed, actseq); + else if(type==2) changed |= select_grouped_type_basic(ed, actseq); + else if(type==3) changed |= select_grouped_type_effect(ed, actseq); + else if(type==4) changed |= select_grouped_data(ed, actseq); + else if(type==5) changed |= select_grouped_effect(ed, actseq); + else if(type==6) changed |= select_grouped_effect_link(ed, actseq); + else if(type==7) changed |= select_grouped_time_overlap(ed, actseq); + + if (changed) { + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void SEQUENCER_OT_select_grouped(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Grouped"; + ot->description = "Select all strips grouped by various properties."; + ot->idname = "SEQUENCER_OT_select_grouped"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = sequencer_select_grouped_exec; + ot->poll = sequencer_edit_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first."); + ot->prop = RNA_def_enum(ot->srna, "type", sequencer_prop_select_grouped_types, 0, "Type", ""); +} + -- cgit v1.2.3