Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_sequencer')
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c91
-rw-r--r--source/blender/editors/space_sequencer/sequencer_buttons.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c95
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c194
-rw-r--r--source/blender/editors/space_sequencer/sequencer_modifier.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_proxy.c14
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c150
7 files changed, 281 insertions, 269 deletions
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index a6e7903d1b1..ac31e0e7c37 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -95,6 +95,7 @@ typedef struct SequencerAddData {
#define SEQPROP_NOPATHS (1 << 2)
#define SEQPROP_NOCHAN (1 << 3)
#define SEQPROP_FIT_METHOD (1 << 4)
+#define SEQPROP_VIEW_TRANSFORM (1 << 5)
static const EnumPropertyItem scale_fit_methods[] = {
{SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image to fit within the canvas"},
@@ -152,6 +153,14 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag)
"Fit Method",
"Scale fit method");
}
+
+ if (flag & SEQPROP_VIEW_TRANSFORM) {
+ ot->prop = RNA_def_boolean(ot->srna,
+ "set_view_transform",
+ true,
+ "Set View Transform",
+ "Set appropriate view transform based on media colorspace");
+ }
}
static void sequencer_generic_invoke_path__internal(bContext *C,
@@ -228,7 +237,6 @@ static void load_data_init_from_operator(SeqLoadData *load_data, bContext *C, wm
PropertyRNA *prop;
const bool relative = (prop = RNA_struct_find_property(op->ptr, "relative_path")) &&
RNA_property_boolean_get(op->ptr, prop);
- int is_file = -1;
memset(load_data, 0, sizeof(SeqLoadData));
load_data->start_frame = RNA_int_get(op->ptr, "frame_start");
@@ -242,17 +250,26 @@ static void load_data_init_from_operator(SeqLoadData *load_data, bContext *C, wm
}
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
- /* Full path, file is set by the caller. */
RNA_property_string_get(op->ptr, prop, load_data->path);
- is_file = 1;
+ BLI_strncpy(load_data->name, BLI_path_basename(load_data->path), sizeof(load_data->name));
}
else if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
- /* Full path, file is set by the caller. */
- RNA_property_string_get(op->ptr, prop, load_data->path);
- is_file = 0;
+ char *directory = RNA_string_get_alloc(op->ptr, "directory", NULL, 0);
+
+ if ((prop = RNA_struct_find_property(op->ptr, "files"))) {
+ RNA_PROP_BEGIN (op->ptr, itemptr, prop) {
+ char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
+ BLI_strncpy(load_data->name, filename, sizeof(load_data->name));
+ BLI_snprintf(load_data->path, sizeof(load_data->path), "%s%s", directory, filename);
+ MEM_freeN(filename);
+ break;
+ }
+ RNA_PROP_END;
+ }
+ MEM_freeN(directory);
}
- if ((is_file != -1) && relative) {
+ if (relative) {
BLI_path_rel(load_data->path, BKE_main_blendfile_path(bmain));
}
@@ -276,17 +293,9 @@ static void load_data_init_from_operator(SeqLoadData *load_data, bContext *C, wm
load_data->flags |= SEQ_LOAD_MOVIE_SYNC_FPS;
}
- if (is_file == 1) {
- BLI_strncpy(load_data->name, BLI_path_basename(load_data->path), sizeof(load_data->name));
- }
- else if ((prop = RNA_struct_find_property(op->ptr, "files"))) {
- RNA_PROP_BEGIN (op->ptr, itemptr, prop) {
- char *name = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
- BLI_strncpy(load_data->name, name, sizeof(load_data->name));
- MEM_freeN(name);
- break;
- }
- RNA_PROP_END;
+ if ((prop = RNA_struct_find_property(op->ptr, "set_view_transform")) &&
+ RNA_property_boolean_get(op->ptr, prop)) {
+ load_data->flags |= SEQ_LOAD_SET_VIEW_TRANSFORM;
}
if ((prop = RNA_struct_find_property(op->ptr, "use_multiview")) &&
@@ -373,8 +382,23 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static void sequencer_disable_one_time_properties(bContext *C, wmOperator *op)
+{
+ Editing *ed = SEQ_editing_get(CTX_data_scene(C), false);
+ /* Disable following properties if there are any existing strips, unless overridden by user. */
+ if (ed && ed->seqbasep && ed->seqbasep->first) {
+ if (RNA_struct_find_property(op->ptr, "use_framerate")) {
+ RNA_boolean_set(op->ptr, "use_framerate", false);
+ }
+ if (RNA_struct_find_property(op->ptr, "set_view_transform")) {
+ RNA_boolean_set(op->ptr, "set_view_transform", false);
+ }
+ }
+}
+
static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ sequencer_disable_one_time_properties(C, op);
if (!RNA_struct_property_is_set(op->ptr, "scene")) {
return WM_enum_search_invoke(C, op, event);
}
@@ -707,13 +731,9 @@ static int sequencer_add_movie_strip_invoke(bContext *C,
{
PropertyRNA *prop;
Scene *scene = CTX_data_scene(C);
- Editing *ed = SEQ_editing_get(scene, false);
- /* Only enable "use_framerate" if there aren't any existing strips, unless overridden by user.
- */
- if (ed && ed->seqbasep && ed->seqbasep->first) {
- RNA_boolean_set(op->ptr, "use_framerate", false);
- }
+ sequencer_disable_one_time_properties(C, op);
+
RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene));
/* This is for drag and drop. */
@@ -739,12 +759,11 @@ static void sequencer_add_draw(bContext *UNUSED(C), wmOperator *op)
uiLayout *layout = op->layout;
SequencerAddData *sad = op->customdata;
ImageFormatData *imf = &sad->im_format;
- PointerRNA imf_ptr, ptr;
+ PointerRNA imf_ptr;
/* Main draw call. */
- RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
uiDefAutoButsRNA(
- layout, &ptr, sequencer_add_draw_check_fn, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
+ layout, op->ptr, sequencer_add_draw_check_fn, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
/* Image template. */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
@@ -781,7 +800,8 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY,
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
- sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_FIT_METHOD);
+ sequencer_generic_props__internal(
+ ot, SEQPROP_STARTFRAME | SEQPROP_FIT_METHOD | SEQPROP_VIEW_TRANSFORM);
RNA_def_boolean(ot->srna, "sound", true, "Sound", "Load sound with the movie");
RNA_def_boolean(ot->srna,
"use_framerate",
@@ -990,8 +1010,10 @@ static void sequencer_add_image_strip_load_files(
wmOperator *op, Sequence *seq, SeqLoadData *load_data, const int minframe, const int numdigits)
{
const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders");
-
- SEQ_add_image_set_directory(seq, load_data->path);
+ /* size of Strip->dir. */
+ char directory[768];
+ BLI_split_dir_part(load_data->path, directory, sizeof(directory));
+ SEQ_add_image_set_directory(seq, directory);
if (use_placeholders) {
sequencer_image_seq_reserve_frames(
@@ -1057,8 +1079,9 @@ static int sequencer_add_image_strip_invoke(bContext *C,
PropertyRNA *prop;
Scene *scene = CTX_data_scene(C);
- const SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
- RNA_enum_set(op->ptr, "fit_method", tool_settings->fit_method);
+ sequencer_disable_one_time_properties(C, op);
+
+ RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene));
/* Name set already by drag and drop. */
if (RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) {
@@ -1104,8 +1127,8 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY,
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
- sequencer_generic_props__internal(ot,
- SEQPROP_STARTFRAME | SEQPROP_ENDFRAME | SEQPROP_FIT_METHOD);
+ sequencer_generic_props__internal(
+ ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME | SEQPROP_FIT_METHOD | SEQPROP_VIEW_TRANSFORM);
RNA_def_boolean(ot->srna,
"use_placeholders",
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index 11614d94862..1e0ecfd890e 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -111,10 +111,10 @@ void sequencer_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel metadata");
strcpy(pt->idname, "SEQUENCER_PT_metadata");
strcpy(pt->label, N_("Metadata"));
+ strcpy(pt->category, "Metadata");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->poll = metadata_panel_context_poll;
pt->draw = metadata_panel_context_draw;
- pt->flag |= PANEL_TYPE_DEFAULT_CLOSED;
pt->order = 10;
BLI_addtail(&art->paneltypes, pt);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index e4afb27dd2e..5f831cbf535 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -105,8 +105,6 @@
* it messes up transform. */
#undef SEQ_ALL_BEGIN
#undef SEQ_ALL_END
-#undef SEQ_CURRENT_BEGIN
-#undef SEQ_CURRENT_END
static Sequence *special_seq_update = NULL;
@@ -872,9 +870,9 @@ static void draw_seq_background(Scene *scene,
/* Draw the main strip body. */
if (is_single_image) {
immRectf(pos,
- SEQ_transform_get_left_handle_frame(seq, false),
+ SEQ_transform_get_left_handle_frame(seq),
y1,
- SEQ_transform_get_right_handle_frame(seq, false),
+ SEQ_transform_get_right_handle_frame(seq),
y2);
}
else {
@@ -887,10 +885,12 @@ static void draw_seq_background(Scene *scene,
immUniformColor4ubv(col);
if (seq->startstill) {
- immRectf(pos, seq->startdisp, y1, (float)(seq->start), y2);
+ const float content_start = min_ff(seq->enddisp, seq->start);
+ immRectf(pos, seq->startdisp, y1, content_start, y2);
}
if (seq->endstill) {
- immRectf(pos, (float)(seq->start + seq->len), y1, seq->enddisp, y2);
+ const float content_end = max_ff(seq->startdisp, seq->start + seq->len);
+ immRectf(pos, content_end, y1, seq->enddisp, y2);
}
}
@@ -1107,6 +1107,10 @@ static void draw_seq_strip(const bContext *C,
x2 = (seq->endstill) ? (seq->start + seq->len) : seq->enddisp;
y2 = seq->machine + SEQ_STRIP_OFSTOP;
+ /* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */
+ x1 = min_ff(x1, seq->enddisp);
+ x2 = max_ff(x2, seq->startdisp);
+
float text_margin_y;
bool y_threshold;
if ((sseq->flag & SEQ_SHOW_STRIP_NAME) || (sseq->flag & SEQ_SHOW_STRIP_SOURCE) ||
@@ -1524,10 +1528,10 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C,
ImBuf *ibuf,
bool *r_glsl_used,
eGPUTextureFormat *r_format,
- eGPUDataFormat *r_data)
+ eGPUDataFormat *r_data,
+ void **r_buffer_cache_handle)
{
void *display_buffer;
- void *cache_handle = NULL;
bool force_fallback = false;
*r_glsl_used = false;
force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
@@ -1580,13 +1584,10 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C,
/* There is data to be displayed, but GLSL is not initialized
* properly, in this case we fallback to CPU-based display transform. */
if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) {
- display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+ display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, r_buffer_cache_handle);
*r_format = GPU_RGBA8;
*r_data = GPU_DATA_UBYTE;
}
- if (cache_handle) {
- IMB_display_buffer_release(cache_handle);
- }
return display_buffer;
}
@@ -1660,6 +1661,7 @@ static void sequencer_draw_display_buffer(const bContext *C,
bool draw_backdrop)
{
void *display_buffer;
+ void *buffer_cache_handle = NULL;
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
GPU_blend(GPU_BLEND_ALPHA);
@@ -1687,7 +1689,8 @@ static void sequencer_draw_display_buffer(const bContext *C,
data = GPU_DATA_UBYTE;
}
else {
- display_buffer = sequencer_OCIO_transform_ibuf(C, ibuf, &glsl_used, &format, &data);
+ display_buffer = sequencer_OCIO_transform_ibuf(
+ C, ibuf, &glsl_used, &format, &data, &buffer_cache_handle);
}
if (draw_backdrop) {
@@ -1747,6 +1750,10 @@ static void sequencer_draw_display_buffer(const bContext *C,
IMB_colormanagement_finish_glsl_draw();
}
+ if (buffer_cache_handle) {
+ IMB_display_buffer_release(buffer_cache_handle);
+ }
+
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
GPU_blend(GPU_BLEND_NONE);
}
@@ -2358,6 +2365,31 @@ static void draw_cache_view(const bContext *C)
}
/* Draw sequencer timeline. */
+static void draw_overlap_frame_indicator(const struct Scene *scene, const View2D *v2d)
+{
+ int overlap_frame = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ?
+ scene->ed->over_cfra :
+ scene->r.cfra + scene->ed->over_ofs;
+
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ /* Shader may have color set from past usage - reset it. */
+ immUniform1i("colors_len", 0);
+ immUniform1f("dash_width", 20.0f * U.pixelsize);
+ immUniform1f("dash_factor", 0.5f);
+ immUniformThemeColor(TH_CFRAME);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, overlap_frame, v2d->cur.ymin);
+ immVertex2f(pos, overlap_frame, v2d->cur.ymax);
+ immEnd();
+
+ immUnbindProgram();
+}
+
void draw_timeline_seq(const bContext *C, ARegion *region)
{
Scene *scene = CTX_data_scene(C);
@@ -2417,31 +2449,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
cfra_flag |= DRAWCFRA_UNIT_SECONDS;
}
- /* Draw overlap frame frame indicator. */
- if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) {
- int overlap_frame = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ?
- scene->ed->over_cfra :
- scene->r.cfra + scene->ed->over_ofs;
-
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
- /* Shader may have color set from past usage - reset it. */
- immUniform1i("colors_len", 0);
- immUniform1f("dash_width", 20.0f * U.pixelsize);
- immUniform1f("dash_factor", 0.5f);
- immUniformThemeColor(TH_CFRAME);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, overlap_frame, v2d->cur.ymin);
- immVertex2f(pos, overlap_frame, v2d->cur.ymax);
- immEnd();
-
- immUnbindProgram();
- }
-
UI_view2d_view_orthoSpecial(region, v2d, 1);
int marker_draw_flag = DRAW_MARKERS_MARGIN;
if (sseq->flag & SEQ_SHOW_MARKERS) {
@@ -2449,11 +2456,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
}
UI_view2d_view_ortho(v2d);
-
- if (ed) {
- draw_cache_view(C);
- }
-
ANIM_draw_previewrange(C, v2d, 1);
/* Draw registered callbacks. */
@@ -2479,6 +2481,13 @@ void draw_timeline_seq_display(const bContext *C, ARegion *region)
const SpaceSeq *sseq = CTX_wm_space_seq(C);
View2D *v2d = &region->v2d;
+ if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) {
+ UI_view2d_view_ortho(v2d);
+ draw_cache_view(C);
+ draw_overlap_frame_indicator(scene, v2d);
+ UI_view2d_view_restore(C);
+ }
+
ED_time_scrub_draw_current_frame(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
UI_view2d_scrollers_draw(v2d, NULL);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 78d263dffad..1c9b3676b19 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -34,6 +34,7 @@
#include "BLT_translation.h"
+#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
#include "DNA_sound_types.h"
@@ -138,6 +139,42 @@ bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq)
ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF));
}
+static bool sequencer_fcurves_targets_color_strip(const FCurve *fcurve)
+{
+ if (!BLI_str_startswith(fcurve->rna_path, "sequence_editor.sequences_all[\"")) {
+ return false;
+ }
+
+ if (!BLI_str_endswith(fcurve->rna_path, "\"].color")) {
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Check if there is animation attached to a strip, that is shown on the strip in the UI.
+ *
+ * - Colors of color strips are displayed on the strip itself.
+ */
+bool ED_space_sequencer_has_visible_animation_on_strip(const struct Scene *scene)
+{
+ if (!scene->adt) {
+ return false;
+ }
+ if (!scene->adt->action) {
+ return false;
+ }
+
+ LISTBASE_FOREACH (FCurve *, fcurve, &scene->adt->action->curves) {
+ if (sequencer_fcurves_targets_color_strip(fcurve)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -290,7 +327,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
snap_frame = RNA_int_get(op->ptr, "frame");
- /* Check metas. */
+ /* Check meta-strips. */
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK) &&
SEQ_transform_sequence_can_be_translated(seq)) {
@@ -312,8 +349,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
}
}
- /* Test for effects and overlap.
- * Don't use SEQ_CURRENT_BEGIN since that would be recursive. */
+ /* Test for effects and overlap. */
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) {
seq->flag &= ~SEQ_OVERLAP;
@@ -349,7 +385,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
}
}
- SEQ_sort(scene);
+ SEQ_sort(SEQ_active_seqbase_get(ed));
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -558,7 +594,7 @@ static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
seq->endofs = endframe - seq->enddisp;
changed = true;
}
- else if (endframe <= seq->enddisp) {
+ else {
seq->endstill = seq->enddisp - endframe;
seq->endofs = 0;
changed = true;
@@ -569,7 +605,7 @@ static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
seq->startofs = 0;
changed = true;
}
- else if (seq->start <= seq->startdisp) {
+ else {
seq->startstill = 0;
seq->startofs = seq->startdisp - seq->start;
changed = true;
@@ -1411,28 +1447,25 @@ static int sequencer_split_exec(bContext *C, wmOperator *op)
}
if (changed) { /* Got new strips? */
- Sequence *seq;
if (ignore_selection) {
if (use_cursor_position) {
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (seq->enddisp == split_frame && seq->machine == split_channel) {
seq_selected = seq->flag & SEQ_ALLSEL;
}
}
- SEQ_CURRENT_END;
if (!seq_selected) {
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (seq->startdisp == split_frame && seq->machine == split_channel) {
seq->flag &= ~SEQ_ALLSEL;
}
}
- SEQ_CURRENT_END;
}
}
}
else {
if (split_side != SEQ_SIDE_BOTH) {
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (split_side == SEQ_SIDE_LEFT) {
if (seq->startdisp >= split_frame) {
seq->flag &= ~SEQ_ALLSEL;
@@ -1444,11 +1477,10 @@ static int sequencer_split_exec(bContext *C, wmOperator *op)
}
}
}
- SEQ_CURRENT_END;
}
}
- SEQ_sort(scene);
+ SEQ_sort(SEQ_active_seqbase_get(ed));
}
if (changed) {
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -1496,19 +1528,16 @@ static void sequencer_split_ui(bContext *UNUSED(C), wmOperator *op)
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
- PointerRNA ptr;
- RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
-
uiLayout *row = uiLayoutRow(layout, false);
- uiItemR(row, &ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- uiItemR(layout, &ptr, "frame", 0, NULL, ICON_NONE);
- uiItemR(layout, &ptr, "side", 0, NULL, ICON_NONE);
+ uiItemR(row, op->ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "frame", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "side", 0, NULL, ICON_NONE);
uiItemS(layout);
- uiItemR(layout, &ptr, "use_cursor_position", 0, NULL, ICON_NONE);
- if (RNA_boolean_get(&ptr, "use_cursor_position")) {
- uiItemR(layout, &ptr, "channel", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "use_cursor_position", 0, NULL, ICON_NONE);
+ if (RNA_boolean_get(op->ptr, "use_cursor_position")) {
+ uiItemR(layout, op->ptr, "channel", 0, NULL, ICON_NONE);
}
}
@@ -1585,38 +1614,35 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot)
/** \name Duplicate Strips Operator
* \{ */
-static int apply_unique_name_fn(Sequence *seq, void *arg_pt)
-{
- Scene *scene = (Scene *)arg_pt;
- char name[sizeof(seq->name) - 2];
-
- BLI_strncpy_utf8(name, seq->name + 2, sizeof(name));
- SEQ_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
- SEQ_dupe_animdata(scene, name, seq->name + 2);
- return 1;
-}
-
static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene, false);
- ListBase nseqbase = {NULL, NULL};
-
if (ed == NULL) {
return OPERATOR_CANCELLED;
}
- SEQ_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT, 0);
+ Sequence *active_seq = SEQ_select_active_get(scene);
+ ListBase duplicated = {NULL, NULL};
- if (nseqbase.first) {
- Sequence *seq = nseqbase.first;
+ SEQ_sequence_base_dupli_recursive(scene, scene, &duplicated, ed->seqbasep, 0, 0);
+ ED_sequencer_deselect_all(scene);
+
+ if (duplicated.first) {
+ Sequence *seq = duplicated.first;
/* Rely on the nseqbase list being added at the end.
* Their UUIDs has been re-generated by the SEQ_sequence_base_dupli_recursive(), */
- BLI_movelisttolist(ed->seqbasep, &nseqbase);
+ BLI_movelisttolist(ed->seqbasep, &duplicated);
+ /* Handle duplicated strips: set active, select, ensure unique name and duplicate animation
+ * data. */
for (; seq; seq = seq->next) {
- SEQ_iterator_recursive_apply(seq, apply_unique_name_fn, scene);
+ if (active_seq != NULL && STREQ(seq->name, active_seq->name)) {
+ SEQ_select_active_set(scene, seq);
+ }
+ seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK);
+ SEQ_ensure_unique_name(seq, scene);
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -1652,16 +1678,14 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene, false);
- Sequence *seq;
SEQ_prefetch_stop(scene);
- SEQ_CURRENT_BEGIN (scene->ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (seq->flag & SELECT) {
SEQ_edit_flag_for_removal(scene, ed->seqbasep, seq);
}
}
- SEQ_CURRENT_END;
SEQ_edit_remove_flagged_sequences(scene, ed->seqbasep);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
@@ -1789,8 +1813,8 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
/* if (seq->ipo) id_us_min(&seq->ipo->id); */
/* XXX, remove fcurve and assign to split image strips */
- start_ofs = timeline_frame = SEQ_transform_get_left_handle_frame(seq, false);
- frame_end = SEQ_transform_get_right_handle_frame(seq, false);
+ start_ofs = timeline_frame = SEQ_transform_get_left_handle_frame(seq);
+ frame_end = SEQ_transform_get_right_handle_frame(seq);
while (timeline_frame < frame_end) {
/* New seq. */
@@ -1839,7 +1863,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
}
}
- SEQ_sort(scene);
+ SEQ_sort(SEQ_active_seqbase_get(ed));
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -1877,13 +1901,13 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
Sequence *active_seq = SEQ_select_active_get(scene);
if (active_seq && active_seq->type == SEQ_TYPE_META && active_seq->flag & SELECT) {
- /* Enter metastrip. */
+ /* Enter meta-strip. */
SEQ_meta_stack_alloc(ed, active_seq);
SEQ_seqbase_active_set(ed, &active_seq->seqbase);
SEQ_select_active_set(scene, NULL);
}
else {
- /* Exit metastrip if possible. */
+ /* Exit meta-strip if possible. */
if (BLI_listbase_is_empty(&ed->metastack)) {
return OPERATOR_CANCELLED;
}
@@ -1905,7 +1929,7 @@ void SEQUENCER_OT_meta_toggle(wmOperatorType *ot)
/* Identifiers. */
ot->name = "Toggle Meta Strip";
ot->idname = "SEQUENCER_OT_meta_toggle";
- ot->description = "Toggle a metastrip (to edit enclosed strips)";
+ ot->description = "Toggle a meta-strip (to edit enclosed strips)";
/* Api callbacks. */
ot->exec = sequencer_meta_toggle_exec;
@@ -1973,7 +1997,7 @@ void SEQUENCER_OT_meta_make(wmOperatorType *ot)
/* Identifiers. */
ot->name = "Make Meta Strip";
ot->idname = "SEQUENCER_OT_meta_make";
- ot->description = "Group selected strips into a metastrip";
+ ot->description = "Group selected strips into a meta-strip";
/* Api callbacks. */
ot->exec = sequencer_meta_make_exec;
@@ -2024,7 +2048,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- SEQ_sort(scene);
+ SEQ_sort(active_seqbase);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -2036,7 +2060,7 @@ void SEQUENCER_OT_meta_separate(wmOperatorType *ot)
/* Identifiers. */
ot->name = "UnMeta Strip";
ot->idname = "SEQUENCER_OT_meta_separate";
- ot->description = "Put the contents of a metastrip back in the sequencer";
+ ot->description = "Put the contents of a meta-strip back in the sequencer";
/* Api callbacks. */
ot->exec = sequencer_meta_separate_exec;
@@ -2247,7 +2271,7 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op)
}
}
- SEQ_sort(scene);
+ SEQ_sort(SEQ_active_seqbase_get(ed));
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -2284,43 +2308,45 @@ void SEQUENCER_OT_swap(wmOperatorType *ot)
static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op))
{
- int retval = OPERATOR_CANCELLED;
Scene *scene = CTX_data_scene(C);
Sequence *active_seq = SEQ_select_active_get(scene);
StripElem *se = NULL;
- if (active_seq == NULL) {
+ if (active_seq == NULL || active_seq->strip == NULL) {
return OPERATOR_CANCELLED;
}
- if (active_seq->strip) {
- switch (active_seq->type) {
- case SEQ_TYPE_IMAGE:
- se = SEQ_render_give_stripelem(active_seq, scene->r.cfra);
- break;
- case SEQ_TYPE_MOVIE:
- se = active_seq->strip->stripdata;
- break;
- case SEQ_TYPE_SCENE:
- case SEQ_TYPE_META:
- case SEQ_TYPE_SOUND_RAM:
- case SEQ_TYPE_SOUND_HD:
- default:
- break;
- }
+ switch (active_seq->type) {
+ case SEQ_TYPE_IMAGE:
+ se = SEQ_render_give_stripelem(active_seq, scene->r.cfra);
+ break;
+ case SEQ_TYPE_MOVIE:
+ se = active_seq->strip->stripdata;
+ break;
+ default:
+ return OPERATOR_CANCELLED;
}
- if (se) {
- /* Prevent setting the render size if sequence values aren't initialized. */
- if ((se->orig_width > 0) && (se->orig_height > 0)) {
- scene->r.xsch = se->orig_width;
- scene->r.ysch = se->orig_height;
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- retval = OPERATOR_FINISHED;
- }
+ if (se == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Prevent setting the render size if sequence values aren't initialized. */
+ if (se->orig_width <= 0 || se->orig_height <= 0) {
+ return OPERATOR_CANCELLED;
}
- return retval;
+ scene->r.xsch = se->orig_width;
+ scene->r.ysch = se->orig_height;
+
+ active_seq->strip->transform->scale_x = active_seq->strip->transform->scale_y = 1.0f;
+ active_seq->strip->transform->xofs = active_seq->strip->transform->yofs = 0.0f;
+
+ SEQ_relations_invalidate_cache_preprocessed(scene, active_seq);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+
+ return OPERATOR_FINISHED;
}
void SEQUENCER_OT_rendersize(wmOperatorType *ot)
@@ -2418,17 +2444,15 @@ void SEQUENCER_OT_copy(wmOperatorType *ot)
void ED_sequencer_deselect_all(Scene *scene)
{
- Sequence *seq;
Editing *ed = SEQ_editing_get(scene, false);
if (ed == NULL) {
return;
}
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
seq->flag &= ~SEQ_ALLSEL;
}
- SEQ_CURRENT_END;
}
static int sequencer_paste_exec(bContext *C, wmOperator *op)
@@ -2475,7 +2499,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
for (iseq = iseq_first; iseq; iseq = iseq->next) {
/* Make sure, that pasted strips have unique names. */
- SEQ_iterator_recursive_apply(iseq, apply_unique_name_fn, scene);
+ SEQ_ensure_unique_name(iseq, scene);
/* Translate after name has been changed, otherwise this will affect animdata of original
* strip. */
SEQ_transform_translate_sequence(scene, iseq, ofs);
@@ -3074,7 +3098,7 @@ static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op)
scene->r.efra = efra;
}
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME_RANGE, scene);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c
index f11a879912c..9b3ecacceb9 100644
--- a/source/blender/editors/space_sequencer/sequencer_modifier.c
+++ b/source/blender/editors/space_sequencer/sequencer_modifier.c
@@ -230,14 +230,13 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Editing *ed = scene->ed;
Sequence *seq = SEQ_select_active_get(scene);
- Sequence *seq_iter;
const int type = RNA_enum_get(op->ptr, "type");
if (!seq || !seq->modifiers.first) {
return OPERATOR_CANCELLED;
}
- SEQ_CURRENT_BEGIN (ed, seq_iter) {
+ LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) {
if (seq_iter->flag & SELECT) {
if (seq_iter == seq) {
continue;
@@ -259,7 +258,6 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op)
SEQ_modifier_list_copy(seq_iter, seq);
}
}
- SEQ_CURRENT_END;
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
diff --git a/source/blender/editors/space_sequencer/sequencer_proxy.c b/source/blender/editors/space_sequencer/sequencer_proxy.c
index e44afde371a..2dcc2d389d9 100644
--- a/source/blender/editors/space_sequencer/sequencer_proxy.c
+++ b/source/blender/editors/space_sequencer/sequencer_proxy.c
@@ -58,7 +58,6 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports)
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene, false);
ScrArea *area = CTX_wm_area(C);
- Sequence *seq;
if (ed == NULL) {
return;
@@ -70,7 +69,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports)
GSet *file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list");
bool selected = false; /* Check for no selected strips */
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (!ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE) || (seq->flag & SELECT) == 0) {
continue;
}
@@ -92,7 +91,6 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports)
BKE_reportf(reports, RPT_WARNING, "Overwrite is not checked for %s, skipping", seq->name);
}
}
- SEQ_CURRENT_END;
BLI_gset_free(file_list, MEM_freeN);
@@ -101,7 +99,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports)
return;
}
- if (selected && !WM_jobs_is_running(wm_job)) {
+ if (!WM_jobs_is_running(wm_job)) {
G.is_break = false;
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
@@ -124,7 +122,6 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
struct Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene, false);
- Sequence *seq;
GSet *file_list;
if (ed == NULL) {
@@ -133,7 +130,7 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list");
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if ((seq->flag & SELECT)) {
ListBase queue = {NULL, NULL};
LinkData *link;
@@ -150,7 +147,6 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
}
}
- SEQ_CURRENT_END;
BLI_gset_free(file_list, MEM_freeN);
@@ -189,7 +185,6 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene, false);
- Sequence *seq;
bool proxy_25 = RNA_boolean_get(op->ptr, "proxy_25");
bool proxy_50 = RNA_boolean_get(op->ptr, "proxy_50");
bool proxy_75 = RNA_boolean_get(op->ptr, "proxy_75");
@@ -201,7 +196,7 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op)
turnon = false;
}
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if ((seq->flag & SELECT)) {
if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE)) {
SEQ_proxy_set(seq, turnon);
@@ -246,7 +241,6 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op)
}
}
}
- SEQ_CURRENT_END;
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 5f0a18fbd0b..7e515271b13 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -26,7 +26,6 @@
#include <string.h>
#include "BLI_blenlib.h"
-#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -43,6 +42,7 @@
#include "SEQ_iterator.h"
#include "SEQ_select.h"
#include "SEQ_sequencer.h"
+#include "SEQ_time.h"
#include "SEQ_transform.h"
/* For menu, popup, icons, etc. */
@@ -548,14 +548,14 @@ static int sequencer_select_exec(bContext *C, wmOperator *op)
const float x = UI_view2d_region_to_view_x(v2d, mval[0]);
- SEQ_CURRENT_BEGIN (ed, seq) {
- if (((x < CFRA) && (seq->enddisp <= CFRA)) || ((x >= CFRA) && (seq->startdisp >= CFRA))) {
+ LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) {
+ if (((x < CFRA) && (seq_iter->enddisp <= CFRA)) ||
+ ((x >= CFRA) && (seq_iter->startdisp >= CFRA))) {
/* Select left or right. */
- seq->flag |= SELECT;
- recurs_sel_seq(seq);
+ seq_iter->flag |= SELECT;
+ recurs_sel_seq(seq_iter);
}
}
- SEQ_CURRENT_END;
{
SpaceSeq *sseq = CTX_wm_space_seq(C);
@@ -808,7 +808,7 @@ static bool select_linked_internal(Scene *scene)
bool changed = false;
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
- if ((seq->flag & SELECT) != 0) {
+ if ((seq->flag & SELECT) == 0) {
continue;
}
/* Only get unselected neighbors. */
@@ -1170,7 +1170,6 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op)
Editing *ed = SEQ_editing_get(scene, false);
const bool extend = RNA_boolean_get(op->ptr, "extend");
const int side = RNA_enum_get(op->ptr, "side");
- Sequence *seq;
if (ed == NULL) {
return OPERATOR_CANCELLED;
@@ -1179,7 +1178,7 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op)
ED_sequencer_deselect_all(scene);
}
const int timeline_frame = CFRA;
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
bool test = false;
switch (side) {
case -1:
@@ -1188,8 +1187,8 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op)
case 1:
test = (timeline_frame <= seq->startdisp);
break;
- case 0:
- test = (timeline_frame <= seq->enddisp) && (timeline_frame >= seq->startdisp);
+ case 2:
+ test = SEQ_time_strip_intersects_frame(seq, timeline_frame);
break;
}
@@ -1198,7 +1197,6 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op)
recurs_sel_seq(seq);
}
}
- SEQ_CURRENT_END;
ED_outliner_select_sync_from_sequence_tag(C);
@@ -1212,6 +1210,7 @@ void SEQUENCER_OT_select_side_of_frame(wmOperatorType *ot)
static const EnumPropertyItem sequencer_select_left_right_types[] = {
{-1, "LEFT", 0, "Left", "Select to the left of the current frame"},
{1, "RIGHT", 0, "Right", "Select to the right of the current frame"},
+ {2, "CURRENT", 0, "Current Frame", "Select intersecting with the current frame"},
{0, NULL, 0, NULL, NULL},
};
@@ -1483,58 +1482,51 @@ static const EnumPropertyItem sequencer_prop_select_grouped_types[] = {
static bool select_grouped_type(Editing *ed, Sequence *actseq, const int channel)
{
- Sequence *seq;
bool changed = false;
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == actseq->type) {
seq->flag |= SELECT;
changed = true;
}
}
- SEQ_CURRENT_END;
return changed;
}
static bool select_grouped_type_basic(Editing *ed, Sequence *actseq, const int channel)
{
- Sequence *seq;
bool changed = false;
const bool is_sound = SEQ_IS_SOUND(actseq);
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (SEQ_CHANNEL_CHECK(seq, channel) && (is_sound ? SEQ_IS_SOUND(seq) : !SEQ_IS_SOUND(seq))) {
seq->flag |= SELECT;
changed = true;
}
}
- SEQ_CURRENT_END;
return changed;
}
static bool select_grouped_type_effect(Editing *ed, Sequence *actseq, const int channel)
{
- Sequence *seq;
bool changed = false;
const bool is_effect = SEQ_IS_EFFECT(actseq);
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (SEQ_CHANNEL_CHECK(seq, channel) &&
(is_effect ? SEQ_IS_EFFECT(seq) : !SEQ_IS_EFFECT(seq))) {
seq->flag |= SELECT;
changed = true;
}
}
- SEQ_CURRENT_END;
return changed;
}
static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel)
{
- Sequence *seq;
bool changed = false;
const char *dir = actseq->strip ? actseq->strip->dir : NULL;
@@ -1543,45 +1535,41 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel
}
if (SEQ_HAS_PATH(actseq) && dir) {
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (SEQ_CHANNEL_CHECK(seq, channel) && SEQ_HAS_PATH(seq) && seq->strip &&
STREQ(seq->strip->dir, dir)) {
seq->flag |= SELECT;
changed = true;
}
}
- SEQ_CURRENT_END;
}
else if (actseq->type == SEQ_TYPE_SCENE) {
Scene *sce = actseq->scene;
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_SCENE && seq->scene == sce) {
seq->flag |= SELECT;
changed = true;
}
}
- SEQ_CURRENT_END;
}
else if (actseq->type == SEQ_TYPE_MOVIECLIP) {
MovieClip *clip = actseq->clip;
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_MOVIECLIP &&
seq->clip == clip) {
seq->flag |= SELECT;
changed = true;
}
}
- SEQ_CURRENT_END;
}
else if (actseq->type == SEQ_TYPE_MASK) {
struct Mask *mask = actseq->mask;
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_MASK && seq->mask == mask) {
seq->flag |= SELECT;
changed = true;
}
}
- SEQ_CURRENT_END;
}
return changed;
@@ -1589,7 +1577,6 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel
static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int channel)
{
- Sequence *seq;
bool changed = false;
bool effects[SEQ_TYPE_MAX + 1];
@@ -1597,15 +1584,14 @@ static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int chann
effects[i] = false;
}
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (SEQ_CHANNEL_CHECK(seq, channel) && (seq->type & SEQ_TYPE_EFFECT) &&
ELEM(actseq, seq->seq1, seq->seq2, seq->seq3)) {
effects[seq->type] = true;
}
}
- SEQ_CURRENT_END;
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (SEQ_CHANNEL_CHECK(seq, channel) && effects[seq->type]) {
if (seq->seq1) {
seq->seq1->flag |= SELECT;
@@ -1619,86 +1605,65 @@ static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int chann
changed = true;
}
}
- SEQ_CURRENT_END;
return changed;
}
static bool select_grouped_time_overlap(Editing *ed, Sequence *actseq)
{
- Sequence *seq;
bool changed = false;
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (seq->startdisp < actseq->enddisp && seq->enddisp > actseq->startdisp) {
seq->flag |= SELECT;
changed = true;
}
}
- SEQ_CURRENT_END;
return changed;
}
-static bool select_grouped_effect_link(Editing *ed, Sequence *actseq, const int channel)
+/* Query strips that are in lower channel and intersect in time with seq_reference. */
+static void query_lower_channel_strips(Sequence *seq_reference,
+ ListBase *seqbase,
+ SeqCollection *collection)
{
- Sequence *seq = NULL;
- bool changed = false;
- const bool is_audio = ((actseq->type == SEQ_TYPE_META) || SEQ_IS_SOUND(actseq));
- int startdisp = actseq->startdisp;
- int enddisp = actseq->enddisp;
- int machine = actseq->machine;
- SeqIterator iter;
-
- SEQ_CURRENT_BEGIN (ed, seq) {
- seq->tmp = NULL;
- }
- SEQ_CURRENT_END;
-
- actseq->tmp = POINTER_FROM_INT(true);
-
- for (SEQ_iterator_begin(ed, &iter, true); iter.valid; SEQ_iterator_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_CHANNEL_CHECK(seq, channel) || (seq->flag & SELECT) || (seq->startdisp >= enddisp) ||
- (seq->enddisp < startdisp) || (!is_audio && SEQ_IS_SOUND(seq)) ||
- (is_audio && !((seq->type == SEQ_TYPE_META) || SEQ_IS_SOUND(seq)))) {
- continue;
+ LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
+ if (seq_test->machine > seq_reference->machine) {
+ continue; /* Not lower channel. */
}
+ if (seq_test->enddisp <= seq_reference->startdisp ||
+ seq_test->startdisp >= seq_reference->enddisp) {
+ continue; /* Not intersecting in time. */
+ }
+ SEQ_collection_append_strip(seq_test, collection);
+ }
+}
- /* If the seq is an effect one, we need extra checking. */
- 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 = POINTER_FROM_INT(true);
+/* Select all strips within time range and with lower channel of initial selection. Then select
+ * effect chains of these strips. */
+static bool select_grouped_effect_link(Editing *ed,
+ Sequence *UNUSED(actseq),
+ const int UNUSED(channel))
+{
+ ListBase *seqbase = SEQ_active_seqbase_get(ed);
- seq->flag |= SELECT;
- changed = true;
+ /* Get collection of strips. */
+ SeqCollection *collection = SEQ_query_selected_strips(seqbase);
+ const int selected_strip_count = BLI_gset_len(collection->set);
+ SEQ_collection_expand(seqbase, collection, query_lower_channel_strips);
+ SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain);
- /* Unfortunately, we must restart checks from the beginning. */
- SEQ_iterator_end(&iter);
- SEQ_iterator_begin(ed, &iter, true);
- }
+ /* Check if other strips will be affected. */
+ const bool changed = BLI_gset_len(collection->set) > selected_strip_count;
- /* Video strips below active one, or any strip for audio (order doesn't matter here). */
- else if (seq->machine < machine || is_audio) {
- seq->flag |= SELECT;
- changed = true;
- }
+ /* Actual logic. */
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, collection) {
+ seq->flag |= SELECT;
}
- SEQ_iterator_end(&iter);
+
+ SEQ_collection_free(collection);
return changed;
}
@@ -1711,7 +1676,7 @@ static int sequencer_select_grouped_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene, false);
- Sequence *seq, *actseq = SEQ_select_active_get(scene);
+ Sequence *actseq = SEQ_select_active_get(scene);
if (actseq == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active sequence!");
@@ -1725,11 +1690,10 @@ static int sequencer_select_grouped_exec(bContext *C, wmOperator *op)
bool changed = false;
if (!extend) {
- SEQ_CURRENT_BEGIN (ed, seq) {
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
seq->flag &= ~SELECT;
changed = true;
}
- SEQ_CURRENT_END;
}
switch (type) {